Proposal: FirstClassFieldUpdates

Jon Fairbairn jon.fairbairn at cl.cam.ac.uk
Mon Jul 27 04:38:25 EDT 2009


According to the wiki, since I'm not a committee member, I should post
proposals here. See below my reply to Isaac's message.

Isaac Dupree
<ml at isaac.cedarswampstudios.org>
writes:

> Jon Fairbairn wrote:
>> Ian Lynagh <igloo at earth.li> writes:
>> [field update] /has/ the
>> binding level of function application. ie, instead of a{x=42} one would
>> have to write {x=42}a,
>
> we already know which record type it is, because record
> fields don't have disambiguation.

OK, I'd forgotten that. Makes things straightforward.

> I think it wouldn't be a terrible syntax, ({...}), kind of
> like infix operators can be made into functions like (+).
> If you wanted to make a proposal for such an extension.

I was wondering how to make it compatible. That looks like a reasonable
compromise, so...

Proposal: FirstClassFieldUpdates

Summary:
Add some syntax that makes field updates into functions.

Description:

On several occasions I've wanted to pass arguments that modified records
and been disappointed that I have to use a lambda expression.

Parenthesis around updates would make them into functions, ie
({a=1,b=2,...}) would mean the same as (\d -> d{a=1,b=2,...}), but be
more concise. This chimes reasonably well with (+) turning an infix
operator into a function. ({}) would be the (polymorphic) identity
function.

This would permit concise calls to functions with default/optional
parameters:

> data Defaults_for_f = Defaults_for_f {option1::A, option2::B, ...}
> defaults_for_f = Defaults_for_f {option1=default1, ...}

> f options other arguments = let params = options defaults_for_f in ...

allows one to write f ({}) ... (or f id ... if no-one likes ({})) to
call f with the default arguments, or f ({option1 = something_else}) ...
to go away from the defaults.

Discussion:

I would rather make {field1=a, field2=b, ...} a function. ie instead of
a{thing=1} one would write {thing=1} a. In other words {field1=a,
field2=b, ...} would be a notation for the function that is currently
written \d -> d{field1=a, field2=b, ...}. Again we would want empty
record updates {} to be the identity function. We would then remove the
thing{fu=bar} syntax (where thing is a variable).

This would simultaneously simplify the syntax, remove the misleading "f
x {a=b}" bemoaned in StricterLabelledFieldSyntax and make certain use
cases (such as default parameters) more concise. Unfortunately old
programmes wouldn't compile any more¹, but I think that Haskell' is the
place for backwards incompatible changes that simplify things.

The difficulty would be what to do about Constructor{fu=bar}, given that
Constructor is currently defined to operate both as a function and be
used in patterns (there's something fishy about this when the record has
named fields). As yet I haven't thought of a good way of doing that,
hence the current proposal that adds syntax rather than takes it away.


[1] All the errors would be compile time errors.

-- 
Jón Fairbairn                                 Jon.Fairbairn at cl.cam.ac.uk




More information about the Haskell-prime mailing list