GHC support for the new "record" package

Edward Kmett ekmett at gmail.com
Fri Jan 23 23:14:52 UTC 2015


If the level of complaints I received when I stole (#) for use in lens is
any indication, er.. it is in very wide use. It was by far the most
contentious operator I grabbed. ;)

It seems to me that I'd not be in a hurry to both break existing code and
pay a long term syntactic cost when we have options on the table that don't
require either, the "magic Field module" approach that both Eric and I
appear to have arrived at independently side-steps this issue nicely and
appears to result in a better user experience.

Keep in mind, one source of objections to operator-based sigils is that if
you put an sigil at the start of a lens the tax isn't one character but
two, there is a space you now need to avoid (.#) when chaining these
things. "foo.bar" vs. "#foo . #bar" and the latter will always be uglier.

The `import Field (...)` approach results in users never having to pay more
syntactically than with options they have available to them now, and being
class based is even beneficial to folks who don't use Nikita's records.

-Edward

On Fri, Jan 23, 2015 at 5:47 PM, Greg Weber <greg at gregweber.info> wrote:

> If we only add syntax when the language extension is used then we are not
> clobbering everyone. # is not that common of an operator. I would much
> rather upset a few people by taking that operator back when they opt-in to
> turning the extension on than having a worse records implementation.
>
> On Fri, Jan 23, 2015 at 2:23 PM, Edward Kmett <ekmett at gmail.com> wrote:
>
>>
>> On Fri, Jan 23, 2015 at 5:06 PM, Adam Gundry <adam at well-typed.com> wrote:
>>
>>> Thanks for the feedback, Iavor!
>>>
>>> On 23/01/15 19:30, Iavor Diatchki wrote:
>>> > 2. I would propose that we simplify things further, and provide just
>>> one
>>> > class for overloading:
>>> >
>>> > class Field (name :: Symbol)
>>> >             rec   rec'
>>> >             field field'
>>> >   | name rec         -> field
>>> >   , name rec'        -> field'
>>> >   , name rec  field' -> rec'
>>> >   , name rec' field  -> rec
>>> >   where
>>> >   field :: Functor f => Proxy name -> (field -> f field') ->
>>> >                                       (rec   -> f rec')
>>> >
>>> > I don't think we need to go into "lenses" at all, the `field` method
>>> > simply provides a functorial
>>> > update function similar to `mapM`.   Of course, one could use the
>>> `lens`
>>> > library to
>>> > get more functionality but this is entirely up to the programmer.
>>> >
>>> > When the ORF extension is enabled, GHC should simply generate an
>>> > instance of the class,
>>> > in a similar way to what the lens library does
>>>
>>
>> > 3. I like the idea of `#x` desugaring into `field (Proxy :: Proxy "x")`,
>>> > but I don't like the concrete symbol choice:
>>> >   - # is a valid operator and a bunch of libraries use it, so it won't
>>> > be compatible with existing code.
>>>
>>> Ah. I didn't realise that, but assumed it was safe behind -XMagicHash.
>>> Yes, that's no good.
>>>
>>> >   - @x might be a better choice; then you could write things like:
>>> >     view @x      rec
>>> >   set  @x 3    rec
>>> >   over @x (+2) rec
>>>
>>> This could work, though it has the downside that we've been informally
>>> using @ for explicit type application for a long time! Does anyone know
>>> what the status of the proposed ExplicitTypeApplication extension is?
>>
>>
>> I'll confess I've been keen on stealing @foo for the purpose of (Proxy ::
>> Proxy foo) or (Proxy :: Proxy "foo") from the type application stuff for a
>> long time -- primarily because I remain rather dubious about how well the
>> type application stuff can work, once you take a type and it goes through a
>> usage/generalization cycle, the order of the types you can "apply" gets all
>> jumbled up, making type application very difficult to actually use. Proxies
>> on the other hand remain stable. I realize that I'm probably on the losing
>> side of that debate, however. But I think it is fair to say that that
>> little bit of dangling syntax will be a bone that is heavily fought over. ;)
>>
>> >   - another nice idea (due to Eric Mertens, aka glguy), which allows us
>>> > to avoid additional special syntax is as follows:
>>> >     - instead of using special syntax, reuse the module system
>>> >     - designate a "magic" module name (e.g., GHC.Records)
>>> >     - when the renamer sees a name imported from that module, it
>>> > "resolves" the name by desugaring it into whatever we want
>>> >     - For example, if `GHC.Records.x` desugars into `field (Proxy ::
>>> > Proxy "x")`, we could write things like this:
>>> >
>>> > import GHC.Records as R
>>> >
>>> > view R.x      rec
>>> > set  R.x 3    rec
>>> > over R.x (+2) rec
>>>
>>> Interesting; I think Edward suggested something similar earlier in this
>>> thread. Avoiding a special syntax is a definite advantage, but the need
>>> for a qualified name makes composing the resulting lenses a bit tiresome
>>> (R.x.R.y.R.z or R.x . R.y . R.z). I suppose one could do
>>>
>>>     import GHC.Records (x, y, z)
>>>     import MyModule hiding (x, y, z)
>>>
>>> but having to manually hide the selector functions and bring into scope
>>> the lenses is also annoying.
>>
>>
>> In the suggestion I made as a (c) option for how to proceed around field
>> names a few posts back in this thread I was hinting towards having an
>> explicit use of {| foo :: x |} somewhere in the module provide an implicit
>> import of
>>
>> import Field (foo)
>>
>> then users can always reference Field.foo explicitly if they don't have
>> such in local scope, and names all share a common source.
>>
>> Of course this was in the context a Nikita style {| ... |} rather than
>> the ORF { .. }.
>>
>> If the Nikita records didn't make an accessor, because there's no way for
>> them to really do so, then there'd be nothing to conflict with.
>>
>> Being able to use import and use them with ORF-style records would just
>> be gravy then. Users would be able to get those out of the box.
>>
>> -Edward
>>
>> _______________________________________________
>> ghc-devs mailing list
>> ghc-devs at haskell.org
>> http://www.haskell.org/mailman/listinfo/ghc-devs
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20150123/090a7b9e/attachment-0001.html>


More information about the ghc-devs mailing list