From a design perspective, the Value trait in ModularSchemeLattice is currently somewhat abused, in that both a Pointer and a Vector/Cons/String are subclasses of Value. However, only pointers can be part of “real” values (i.e., they are expressible values). In contrast, a vector/pair/string is only bound to an address in the store (i.e., they are storable values). Put differently, a VarAddr and a PtrAddr are both bound to an abstract value of type List[Value] in the store, although the former is actually guaranteed to not contain any Vector/Cons/String in that list, while the latter is guaranteed to find a list of length 1 with a Vector/Cons/String in it. This, however, is not well-reflected in the current design, and not in any way indicated by the type system (which therefore considers more types than necessary and needs extra guidance sometimes).
One possible (though somewhat radical) solution would be to factor storable values (aka "reference types") out of SchemeLattice entirely (so that a VarAddr is always bound to a value of type L (with SchemeLattice[L]), a PaiAddr always to a pair of type P (with PairLattice[P]) and a VecAddr always to a vector of type V (with VectorLattice[V])).
From a design perspective, the
Value
trait inModularSchemeLattice
is currently somewhat abused, in that both aPointer
and aVector
/Cons
/String
are subclasses ofValue
. However, only pointers can be part of “real” values (i.e., they are expressible values). In contrast, a vector/pair/string is only bound to an address in the store (i.e., they are storable values). Put differently, aVarAddr
and aPtrAddr
are both bound to an abstract value of typeList[Value]
in the store, although the former is actually guaranteed to not contain anyVector
/Cons
/String
in that list, while the latter is guaranteed to find a list of length 1 with aVector
/Cons
/String
in it. This, however, is not well-reflected in the current design, and not in any way indicated by the type system (which therefore considers more types than necessary and needs extra guidance sometimes).One possible (though somewhat radical) solution would be to factor storable values (aka "reference types") out of
SchemeLattice
entirely (so that aVarAddr
is always bound to a value of typeL
(withSchemeLattice[L]
), aPaiAddr
always to a pair of typeP
(withPairLattice[P]
) and aVecAddr
always to a vector of typeV
(withVectorLattice[V]
)).