simple extension to ghc's record disambiguation rules

AntC anthony_clayden at clear.net.nz
Mon Feb 20 04:12:57 CET 2012


>>>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-disambiguation-rules-tp5494549p5498022.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at Nabble.com.



More information about the Glasgow-haskell-users mailing list