These are chat archives for mozart/mozart2
Not sure if @betamos is still monitoring this but anyway...
1 Like most elements of language design: because the one designing it thought it to be best. As records are one of the most versatile values in Oz, one could argue that they should support even more feature types. The only types that would be difficult to allow as features are unbound variables and records themselves (as they have structural equality and that is expensive to check). In particular, all token values (eg. procedures, thread or cells) could be added without too much difficulty. By the way, all names, not just booleans, can be used as features in the language as it currently is.
2 & 3. The implementation we use is a bit less straightforward than what you seem to imply. Basically, we use a strategy similar to C# or Java and compile the Oz code to an intermediate assembly-like language that is interpreted by the virtual machine. For more information, you can read the slightly outdated & incomplete documentation but it stays quite similar.
2 All nodes in the Oz memory (corresponding to the single-assignment store + mutable memory of the semantic) are represented by a small two-word structure called a node (See Object model documentation). The first word is a pointer to a type descriptor, the second is (depending on the type) either a value (integer, double, etc.) or a pointer to some type-specific data-structure. The advantage of this structure is that we can easily transform some node to another type, the inconvenience is that nodes are not simply objects of the implementation language. There is one special type that we call Reference which is completely invisible at Oz level. When the type is reference, the second word is a pointer to another node. The unification is done by replacing one of the variable by a reference to the other. Long reference chains can be produced but they are compacted at garbage collection time.
3 The compiler analyses the code of the procedure to determine which identifiers are needed from the defining environment. The procedure-specific data-structure contains an array of nodes (called G registers) that are initialized when the procedure definition is executed. The assembly-like code make reference to these G registers by index. If you want to see how the compiler works, you can check the actual implementation (it's in Oz!) or for a simpler implementation, the bootstrapping compiler (in Scala).