[Haskell-cafe] A backwards-compatible record proposal

Brian Hulley brianh at metamilk.com
Sun Aug 20 06:54:07 EDT 2006

Bulat Ziganshin wrote:
> Hello Brian,
> Saturday, August 19, 2006, 12:21:34 PM, you wrote:
>> ie putting a '.' before each field name. The intended meaning is
>> that dotted field names do *not* generate top level functions.
>> Instead they allow the compiler to generate instance decls as
>> follows, where we've introduced a new form of identifier, the dotted
>> id, which behaves as a postfix operator which binds more tightly
>> than function application and can also be used as a class name (by
>> the compiler only):
>>     class (.x) :: a b | a -> b where
>>         (.x) :: a -> b
> this means that foo.bar should be parsed differently by _lexer_
> depending on is there any .bar field available in current or any
> imported module

Hi Bulat,
I just assumed that foo.bar would always be lexed as "foo" ".bar" so if 
composition was intended there would need to be a space between the "." and 
the "bar", but this breaks backwards compatibility (I hadn't thought of this 
when I made the proposal because I assumed everyone always writes "f . g" 
and not "f.g" when they mean composition but of course the latter is 
currently parsed as composition also).

> How about omitting '.' and using '#' operation for record access? the
> only problem will that '#' should have larger priority than ' '. i.e.
> function application. I had proposal on it, but it's too daring -
> raise priority of operations when they are written without spaces
> around, i.e.
> object#call x+y t#field z*2+1
> treated as
> (object#call) (x+y) (t#field) (z*2+1)

Intuitively this makes sense, because you'd expect no spaces to mean "glue 
this together as tight as possible", but on the other hand I personally find 
the second version with brackets is visually much easier to read even though 
it's a bit more inconvenient to write.

    1) The first version is not backwards compatible either.
    2) object#call should not be treated as (object # call) because it means 
((#call) object) so whatever symbol is used for field selection, it needs to 
be glued onto the field name by the lexer not the parser.

Also I was hoping to be able to use the "." so that field access would 
follow the C, C#, Java conventions and because # is used by ghc to mean 
"unboxed" so the following might be confusing:

    object#call 1# x#y # k (#g,a#)

    object.call 1# x.y # k (#g,a#)

    ((object.call) 1# (x.y)) # (k (# g, a #))

Best regards,
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.


More information about the Haskell-Cafe mailing list