We never reached consensus on how to surface Ref/ValObject. 

Here are some places we might want to use these type names:

 - Parameter types / variables: we might want to restrict the domain of a 
parameter or variable to only hold a reference, or a value: 

    void m(RefObject ro) { … }

 - Type bounds: we might want to restrict the instantiation of a generic class 
to only hold a reference (say, because we’re going to lock on it):

    class Foo<T extends RefObject> { … }

 - Dynamic tests: if locking on a value is to throw, there must be a reasonable 
idiom that users can use to detect lockability without just trying to lock:

    if (x instanceof RefObject) {
        synchronized(x) { … }
    }

 - Ref- or Val-specific methods.  This one is more vague, but its conceivable 
we may want methods on ValObject that are members of all values.  


There’s been three ways proposed (so far) that we might reflect these as top 
types: 

 - RefObject and ValObject are (somewhat special) classes.  We spell (at least 
in the class file) “value class” as “class X extends ValObject”.  We implicitly 
rewrite reference classes at runtime that extend Object to extend RefObject 
instead.  This has obvious pedagogical value, but there are some (small) risks 
of anomalies.  

 - RefObject and ValObject are interfaces.  We ensure that no class can 
implement both.  (Open question whether an interface could extend one or the 
other, acting as an implicit constraint that it only be implemented by value 
classes or reference classes.). Harder to do things like put final 
implementations of wait/notify in ValObject, though maybe this isn’t of as much 
value as it would have been if we’d done this 25 years ago.  

 - Split the difference; ValObject is a class, RefObject is an interface.  
Sounds weird at first, but acknowledges that we’re grafting this on to refs 
after the fact, and eliminates most of the obvious anomalies.  

No matter which way we go, we end up with an odd anomaly: “new Object()” should 
yield an instance of RefObject, but we don’t want Object <: RefObject for 
obvious reasons.  Its possible that “new Object()” could result in an instance 
of a _species_ of Object that implement RefObject… but our theory of species 
doesn’t quite go there and it seems a little silly to add new requirements just 
for this.  



Reply via email to