
| the concrete proposal is to address one of these remaining issues, | namely how to identify record field labels as such. for that, I outlined | three options, although that outline perhaps wasn't concrete enough: | | 1. make label declarations unneccessary (eg., #pointX :: #PointX) | | 2. make type sharing expressible (something like the sharing | constraints in Standard ML's module language, to allow you to | say when two declarations from different imports refer to the | same type) | | 3. introduce a least upper bound for shared label imports | (so A and B could just 'import Data.Label(pointX)', which | would magically provide the shared declaration for pointX) Thanks for the clarifications. But I am still in the dark. I have literally no clue about *exactly* what your suggestions would entail. What would the effect on the type system of (1) be? Or (2) -- is it just a name-space issue or is it something to do with types. Or (3) -- I have even less clue here. Sorry to be dense Simon

| the concrete proposal is to address one of these remaining issues, | namely how to identify record field labels as such. for that, I | outlined three options, although that outline perhaps wasn't concrete | enough: | | 1. make label declarations unneccessary (eg., #pointX :: #PointX) effect on the type system: a new (meta-)rule for a new kind of literal constants: whenever we see something looking like " '#'<identifier> ", its type is " '#'<Identifier>". Essentially the same as for other literals: whenever we see something looking like " [0-9]+ ", its type is " Num a => a ". whenever we see " True ", its type is " Bool ", etc. . Similar to numeric literals, there'd be no place in source where all those literals/labels are declared, but literals of the same type in different modules would be compatible. So this would work without problems: module A main = #pointX module B main = #pointX module C import A import B main = print [A.main,B.main] | 2. make type sharing expressible (something like the sharing | constraints in Standard ML's module language, to allow you to | say when two declarations from different imports refer to the | same type) this is definitely a type system issue. if we have module A where data PointX = PointX deriving Show main = print PointX module B where data PointX = PointX deriving Show main = print PointX module C -- this doesn't work! import A import B main = print PointX -- conflict here! ambiguous occurrence.. we have a problem. in a simple form, the sharing constraints I had in mind would permit us to express which structurally equivalent declarations define *the same type*. that is, module C would be module C import A import B sharing A.PointX B.PointX main = print PointX -- no conflict, A.PointX and B.PointX have been -- identified, refer to the same type the type system would need to unify the shared types. to make that safe, it would need to check for structural equivalence of the declarations when encountering a sharing constraint; if successful, both shared types would afterwards be seen as synonyms for one and the same type. A very minimal version of this option would suffice for labels; in general, this kind of sharing constraints is non-trivial, but useful (if we could share classes and instances defined multiple times, like the instances for (,,,,,,,,,,,) discussed in other threads). | 3. introduce a least upper bound for shared label imports | (so A and B could just 'import Data.Label(pointX)', which | would magically provide the shared declaration for pointX) with this option, the modules would look like this module A import Data.Label(pointX) module B import Data.Label(pointX) module C import A import B main = print pointX -- no conflict, A.pointX and B.pointX are the same this would have a similarly small effect on the type system as option 1, only that instead of syntax, we'd use imports from the reserved module 'Data.Label' to identify what is a label and what is not. whenever encountering an ' import Data.Label(<identifier>) ', we interpret ' Data.Label.<identifier> ' as a constant of type ' Data.Label.<Identifier> ' and ' <identifier> ' as a constant of type ' <Identifier> '. the difference to normal imports is that the compiler/type system needs to know about 'Data.Label'. In other words, 'Data.Label' does not exist in source or object code, but as a hint for the compiler/type system. Any identifier imported from there is a label of its own type, nothing else can be imported from there. sorry for being so difficult to understand. the questions help. cheers, claus

there is now a ticket and a wiki page for this, #92: http://hackage.haskell.org/trac/haskell-prime/ticket/92 we haven't had much discussion yet; in particular noone has said "yes, that makes sense" or "no, we don't need that", but Simon's questions have helped to clarify the initial message a bit, and I thought I'd summarize things, especially as he's away for a bit, and noone else seems to be interested in record-related stuff for haskell'? cheers, claus

Yeah, I had a similar idea and think it would be nice. however I prefer the idea of a 'magic module' so we don't eat up any syntax. import Label now Label.Foo will be a value of type Label.Foo for any value taken from Label. another possibility is to treat a leading ' as special 'foo this would be somewhat reminicent of lispy languages. we would need to be careful to not collide with the character syntax though. John -- John Meacham - ⑆repetae.net⑆john⑈
participants (3)
-
Claus Reinke
-
John Meacham
-
Simon Peyton-Jones