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