simple extension to ghc's record disambiguation rules

Hi, I'd like to propose an extremely simple extension to ghc's record disambiguation rules, my motivation is that I often have record types with multiple constructors but common fields. so the handy idiom of f Rec { .. } = do blah return Rec { .. } won't work, because I don't know the specific constructor. so, my proposal is that when you come across something like (e::RecType) { blah = foo } (with an explicit type signature like shown) You interpret 'blah' as if it is a field of the record of type 'Rec'. This gives the advantages of record field names being scoped by type but without you having to specify the precise constructor. It is also backwards compatible for expressions, but would be a new thing for patterns which generally don't allow type signatures there. It sidesteps type checker interactions by only being triggered when an explicit type annotation is included. ideally it would be combined with the 'update' and 'label-based pattern-matching' extensions from this page http://hackage.haskell.org/trac/haskell-prime/wiki/ExistingRecords John

Hi, I'd like to propose an extremely simple extension to ghc's record disambiguation rules,
I wonder if John is teasing us? Nothing wrt to records is simple (IMHO). John seems to be unaware of the threads on 'Records in Haskell' (ghc-users) or 'Type-Directed Name Resolution' (cafe) that have been storming for the last few months. He refers to a web page ...
ideally it would be combined with the 'update' and 'label-based pattern-matching' extensions from this page http://hackage.haskell.org/trac/haskell-prime/wiki/ExistingRecords
... which is several years old, requesting features that have been largely delivered in ghc's -XDIsambiguateRecordFields, -XNamedFieldPuns, and -XRecordWildCards.
my motivation is that I often have record types with multiple constructors but common fields.
Perhaps this is a different requirement to those threads above? Most are dealing with the namespacing problem of common fields in different record types. I think John means common fields under different constructors within the same type(?).
so, my proposal is that when you come across something like
(e::RecType) { blah = foo }
(with an explicit type signature like shown)
It's certainly an innovation to go looking for an explicit type sig. within an expression. Does anything else in Haskell do that?
It ... would be a new thing for patterns which generally don't allow type signatures there.
It sidesteps type checker interactions by only being triggered when an explicit type annotation is included.
John
"Extremely simple"? I don't think so. I've added a suggested approach to approximate what John is asking for to my DORF proposal. http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFie... -- as a **speculative** **future** development. The ease with which I could do that (both a polymorphic record update _and_ polymorphic record pattern match) suggests my proposal is powerful enough to achieve the limited aims for the namespacing issue, with some headroom. -- But then I would say that, wouldn't I! (By the way, none of the 'Records in Haskell' proposals describe themselves as "extremely simple". http://hackage.haskell.org/trac/ghc/wiki/Records AntC -- View this message in context: http://haskell.1045720.n5.nabble.com/simple-extension-to-ghc-s-record-disamb... Sent from the Haskell - Glasgow-haskell-users mailing list archive at Nabble.com.

On Sun, Feb 19, 2012 at 4:21 PM, AntC
Hi, I'd like to propose an extremely simple extension to ghc's record disambiguation rules, I wonder if John is teasing us? Nothing wrt to records is simple (IMHO).
That is rather defeatist. Degree of simplicity is actually something that very quickly becomes very relevant and apparent as soon as one starts implementing these proposals. Luckily, experience gives us some ability to figure out what will be simple and what won't be.
John seems to be unaware of the threads on 'Records in Haskell' (ghc-users) or 'Type-Directed Name Resolution' (cafe) that have been storming for the last few months.
Trust me, I am completely aware of them and have been following these ideas in all their incarnations over the years. Seeing as how I will likely be one of the people that actually implements said ideas, I do keep on top of such things.
He refers to a web page ...
ideally it would be combined with the 'update' and 'label-based pattern-matching' extensions from this page http://hackage.haskell.org/trac/haskell-prime/wiki/ExistingRecords
... which is several years old, requesting features that have been largely delivered in ghc's -XDIsambiguateRecordFields, -XNamedFieldPuns, and -XRecordWildCards.
Neither of those extensions I specifically mention are included in those you list. Nor are in any way delivered by them. Though, those extensions you do list are quite handy indeed and I am glad to see ghc support them and in fact, what I am proposing is dependent on them.
my motivation is that I often have record types with multiple constructors but common fields.
Perhaps this is a different requirement to those threads above? Most are dealing with the namespacing problem of common fields in different record types. I think John means common fields under different constructors within the same type(?).
No, I am trying to deal with namespace problems of common fields in different labled field tyes. I refer to different constructors within the same type because that is where the common mechanisms for dealing with said ambiguities (such as the DisambiguateRecordFields extension) break down when presented with such types. The basic issue is that in order for DisambiguateRecordFields to work it needs an unambiguous indicator of what type the record update is called at, currently it can use the explicit constructor name as said indicator. my proposal is simply to also allow an explicit type to have the same effect.
"Extremely simple"? I don't think so.
Simple can be quantified here pretty easily Ways in which it is simple: * requires no changes to existing desugarings * conservative in that it doesn't change the meaning of existing programs * well tested in that it is an application of an existing extension (DisambiguateRecordFields) to a slighly broader context. Ways in which it is complicated: * record field names now depend on context. (already true with the DisambiguateRecordFields extension.) * requires information transfer from the type checker to the renamer. (or some renaming to be delayed until the type checker). This is a common feature of some proposed extensions out there, however this extension explicitly "cuts the recursive knot" requiring an explicit type signature, so while the renaming is affected by typing, the typing will not be affected by said renaming. A particularly thorny problem to resolve with some other proposals. Your DORF proposal is interesting too, but is not really directly related to this relatively local change to an existing extension. There is no reason to conflate them. John

Hi, I'd like to propose an extremely simple extension to ghc's record disambiguation rules, I wonder if John is teasing us? Nothing wrt to records is simple (IMHO).
That is rather defeatist. Degree of simplicity is actually something that very quickly becomes very relevant and apparent as soon as one starts implementing these proposals. Luckily, experience gives us some ability to figure out what will be simple and what won't be.
John, of course I have huge respect for anybody who can poke inside something as complex as ghc; let alone run their own compiler single-handed.
Trust me, I am completely aware of them and have been following these ideas [for records] in all their incarnations over the years.
And over all those years, despite the dissatisfaction with Haskell 98's record system since at least, errm, 1996, and all the competing proposals, very little has been implemented. Doesn't that mean there's nothing simple in the design space?
ideally it would be combined with the 'update' and 'label-based pattern-matching' extensions from this page
Neither of those extensions I specifically mention are included in those you list. Nor are in any way delivered by them. ...
Well, you're correct on those two extensions not being implemented. I should have said "all the simple features have been largely delivered". Complications with those two that I can see (I'm not saying impossible, just not "extremely simple"): Update: * we can't infer from knowing the type only which is the existing data constructor * what if the mentioned fields are common to all (or most) constructors - which do we choose? * in the 'most' case, what if they don't match the as-is constructor - what do we change to? * what if the mentioned fields have no constructor in common - is this a static error? Label-based pattern matching: * we can't infer from knowing the type only which is the existing data constructor * what if the mentioned fields are common to all (or most) constructors - which do we guess for the pattern? * in the 'most' case, what if they don't match the as-is constructor - is this a run-time error? * what if the mentioned fields have no constructor in common - is this a static error? * what if if there's several case branches (or several equations for a function) do you expect some fancy semantics: to examine whether the as-is constructor has all the mentioned fields and if not drop down to the next branch? But the major non-simple bit I see in your core proposal is "only being triggered when an explicit type annotation is included". Does anything else in Haskell do that? Haskell already supports putting type sigs on pattern terms (as well, of course, as on expressions). And then the whole of Haskell's semantics relies on type inference/instance resolution from the types. Most of the recent 'Records in Haskell' proposals wanted to do some sort of fancy syntax-directed record resolution. I did not like that at all. So DORF uses only familiar type inference/instance resolution. That's how come I could build a prototype. Nothing in DORF supports inferring a change to the to-be data constructor on a record update. And I don't think I'd want it to try: there's just too much opportunity for ambiguity.
The basic issue is that in order for DisambiguateRecordFields to work it needs an unambiguous indicator of what type the record update is called at, currently it can use the explicit constructor name as said indicator. ...
For selection, DORF does not need to know the as-is data constructor. For update, DORF does support changing the data constructor explicitly (via DisambiguateRecordFields), and as-was fields get carried forward under the same name, thanks to NamedFieldPuns and RecordWildCards.
my proposal is simply to also allow an explicit type to have the same effect.
But it doesn't! The type alone doesn't tell us what constructor to use! I don't see this as being simple.
Simple can be quantified here pretty easily
I'll tag your points with a comparison to DORF ...
Ways in which it is simple: * requires no changes to existing desugarings -- DORF likewise * conservative in that it doesn't change the meaning of existing programs -- DORF likewise: existing record decls/access/update still work * well tested in that it is an application of an existing extension (DisambiguateRecordFields) to a slighly broader context. -- DORF likewise
Ways in which it is complicated: * record field names now depend on context. (already true with the DisambiguateRecordFields extension.) -- DORF record field names depend on type inference (well tested) * requires information transfer from the type checker to the renamer. ... -- DORF does not need phase 'knotting' -- there's a syntax desugaring phase -- then usual type inference/instance resolution
Your DORF proposal is interesting too, but is not really directly related to this relatively local change to an existing extension. There is no reason to conflate them.
I think DORF can achieve the "simple" parts of your proposal without introducing the complexity of looking for type annotations. True that it can't achieve the ambiguous parts, but I don't think anything cimple can. AntC -- View this message in context: http://haskell.1045720.n5.nabble.com/simple-extension-to-ghc-s-record-disamb... Sent from the Haskell - Glasgow-haskell-users mailing list archive at Nabble.com.
participants (2)
-
AntC
-
John Meacham