Felix currently has 3 kinds of native products: tuples structs records
And also cstructs. I'm thinking to unify them into a single anonymous type: product sname { f1name: f1type; ... } The way to do this is: A record is just a struct with name "". A tuple is just a record with field names 0,1,2 etc. Now you can also have a named tuple too: product tname { 0:T0; 1:T1; ...} That's the theory. In the compiler only one combinator is used: BTYP_product of string * (string * btype) list Now you can do: typedef A1 = product A1 { .. }; Note the second A1 isn't a type name, its just a tag like a field name. The type name is "product A1 { ... }" i.e. the whole expression. A synonym for the above is: struct A1 { ... }; so we have recovered the struct notation, with the same meaning, but now it is no longer a type put into the symbol table requiring lookup. Field tags can be identifiers or integers.. the integers are implicit from position: struct X { a:int; long; b:int; } The padding long has a name: 1. Field access is by field value That is, the field name is an ordinary production function. Now, the notation value . field is just reverse application. The only hassle is this: struct X { x:int; }; fun x: X -> int = "1"; var a: X = X (x=1;); println$ a . x; // which x? There are some other details, such as struct constructors: that's a special isomorphism from a tuple to a struct in which field and tag names are changed from the "default" ones (empty, integer sequence) to the named ones of the struct. I expect a similar thing can be done with variants.. Now there's an interesting quirk here. Consider: var a: X ... a.x That's a projection function. Now consider: (&a) . x What could that do? Well, it should return a pointer to the x field of a, right? So now we get our store operation: (&a). x <- 42; x (&a) <- 42; If the struct is on the heap and pa is a pointer to it then pa . x <- 42; but we need to use (*pa) . x to get the value. Note that *(pa . x) == (*pa) . x On the other hand & ( a . x ) is nonsense because a is a value. If a is a variable we allow (&a) however, so we should also allow & ( a. x). However, if we have a Cstruct, it is different: A Cstruct is just a collection of projection functions: cstruct X { x: int; }; is shorthand for type X = "X"; fun x: X -> int = "$1.x"; An *abstract struct* can be given by: type X = "X"; fun x: X -> int = "Whatever you like goes here"; In this case we can't allow & ( a . x) because it is an int value. However what if we have this: fun x: &X -> &int = " ... "; pa .x <- 42; // works! (&a) . x <- 42; // works! (if a is a variable) So actually, we're close to also allowing a choice of whether a field is mutable: clearly you can't store calculated fields. Note that a struct with calculated fields is NOT a product!! (Products requires all the fields to be independent). Now, we can actually get rid of the "&" operator altogether if we decide a variable type "int" is actually a pointer. In that case given var px : int = 1; px <- *px; In other words instead of addressing and lvalues, we have pointers and deref only. Getting rid of lvalues is pretty cool. Note we STILL have variables we can store stuff in. The calculus is functional upto the assignment operation: LHS <- RHS Hmmm.. any thoughts? -- john skaller skal...@users.sourceforge.net ------------------------------------------------------------------------------ Free Software Download: Index, Search & Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language