[ghc-steering-committee] Discussion for #158 "Add `setFild` to `HasField`"

Iavor Diatchki iavor.diatchki at gmail.com
Tue Jan 15 19:03:02 UTC 2019


Hello,

I am skeptical about the supposed overlap provided by functional
dependencies that would be unsound with type families.   It would be
extremely odd to accept a "functional" dependency that is not functional.
And if it is functional, then it should not be unsound to generate evidence
for it.   I am also not sure why one would use overlapping things for
records---wouldn't that imply that a record has the same field multiple
times somehow?   So, for me, the overlap benefit of FDs is rather suspect
and I imagine that if it works it is an artifact of the current
implementation rather than something that has been thought about deeply.

On the other hand, I do think that the FD formulation captures more
precisely what is intended in this situation, as the relation between types
and fields is inherently partial (i.e., not all types have all fields).
 As a result, if we used a type family, it would have to be a partial one.
I know that these are commonly used, but I've never been quite comfortable
with the way these "stuck" type families do not always result in a type
error, and sometimes are treated silently as a ordinary types, even though
they are not supposed to really correspond to any type at all.  This does
not happen with constraints, which always result in a type error, if they
can't be solved.

To summarize the current state of the discussion:
   - No one has complained about the main part of the proposal---adding an
update functionality to the record class
   - Simon M would prefer to use a type family for the record field:
Simon, which formulation are you thinking of, 2 or 3 parameter class?
   - Simon PJ would also prefer to use a type family, but due to some
trade-offs is OK with using fun-deps for now.
   - Iavor would prefer to stick with fun-dpes for the reasons above (also,
the change seems quite orthogonal to the proposal)

I haven't heard from anyone else.  While we are not in a big hurry, as I
shepherd of this discussion I would like to move us in the direction of
making a decision.

So I am leaning towards accepting the proposal as is, unless Simon M or
someone else objects strongly.  If you do, please speak up soon.

Cheers,
-Iavor





















On Wed, Jan 9, 2019 at 12:19 AM Simon Marlow <marlowsd at gmail.com> wrote:

> I defer to Simon's judgement on the details, however there's one point
> that I think should be mentioned - unless we get some significant benefit
> from using fundeps here, my preference would be to use type families
> instead purely because it's one fewer extension for people to understand,
> and this is core functionality that many people will likely encounter.
> Fundeps are much less widely used than type families, and it would be nice
> if we could keep them out of core abstractions so that those who don't need
> them don't need to learn about them.
>
> Cheers
> Simon
>
> On Tue, 8 Jan 2019 at 23:46, Simon Peyton Jones via ghc-steering-committee
> <ghc-steering-committee at haskell.org> wrote:
>
>> Yes, I’m fine with accepting as-is.  Actually the discussion has been
>> quite illuminating.  I learned
>>
>>
>>
>>    - An idea for improving inferred types (Trac #16070)
>>    - An understanding that
>>       - Type families are in some ways more expressive because they
>>       support evidence
>>       - But fundeps allow overlap (which for soundness type families
>>       must eschew) and that allows a different kind of expressiveness.
>>
>> So the two overlap, but neither subsumes the other.  And I think the
>> choice is fundamental; the overlap stuff in fundeps is allowed precisely
>> because it only affect unification, and doesn’t turn into evidence.
>>
>>    - For HasField we don’t need overlap.
>>    - However, even if we used a type-family encoding, a 3-parameter
>>    class is probably best, because it leads to briefer types.
>>    - And, absent #16070, the error messages with fundeps are better, and
>>    the extra expressiveness of type families has not (yet) become important
>>    for HasField.
>>
>>
>>
>> Conclusion: use fundeps for now.
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* Iavor Diatchki <iavor.diatchki at gmail.com>
>> *Sent:* 08 January 2019 23:10
>> *To:* Simon Peyton Jones <simonpj at microsoft.com>
>> *Cc:* ghc-steering-committee <ghc-steering-committee at haskell.org>
>> *Subject:* Re: [ghc-steering-committee] Discussion for #158 "Add
>> `setFild` to `HasField`"
>>
>>
>>
>> Hello,
>>
>>
>>
>> does anyone else have any input on this proposal?
>>
>>
>>
>> There has been some discussion on Simon's point about using a type-family
>> instead of a fun-dep.  The outcome of the discussion is a little unclear,
>> but here is a very brief summary to the best of my understanding:
>>
>>    * Either approach works, but with the current GHC implementations both
>> approaches have some pros and some cons.
>>
>>    * Fun-deps (used in the current design) are a bit more restrictive as
>> they do not produce evidence at the moment
>>
>>    * There are two ways to use type families instead of fun-deps:
>>
>>           a) the class has 2 parameters, and the third is computed from
>> them using a type family
>>
>>           b) the class remains with 3 parameters, but it gets a
>> super-class constraint, where a type-family encodes the functional
>> dependency
>>
>>    * Either type family encoding leads to types that look more verbose,
>> both in errors and inferred types.
>>
>>     * There are some ideas about how this might be improved for type
>> families in general (see #16070)
>>
>>
>>
>> The choice of type-families/fun-deps is quite orthogonal to the original
>> proposal, which is about adding a way to update records.  We were
>> discussing it,
>>
>> because it is quite tempting to roll-up multiple interface breaking
>> changes into one.
>>
>>
>>
>> In the interest of making progress, my vote would be to accept the
>> proposal as is, and delay switching to type families to a separate proposal,
>>
>> which might look better once the improvements in #16070 are figured out.
>>
>>
>>
>> What does everyone else think?
>>
>>
>>
>> -Iavor
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> On Wed, Dec 19, 2018 at 1:04 AM Simon Peyton Jones <simonpj at microsoft.com>
>> wrote:
>>
>> Iavor
>>
>>
>>
>> I’m broadly happy, but I would like us (and the proposers) to discuss the
>> question of using a type family instead of a fundep.  See my comment at
>> https://github.com/ghc-proposals/ghc-proposals/pull/158#issuecomment-448520004
>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fghc-proposals%2Fghc-proposals%2Fpull%2F158%23issuecomment-448520004&data=02%7C01%7Csimonpj%40microsoft.com%7C93e0092457d2468378cf08d675be71fd%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636825858153743988&sdata=VvDRQjpINBfDlgwjWVyeokmJSIi3ZOdPvqXKW2gbtSs%3D&reserved=0>
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* ghc-steering-committee <
>> ghc-steering-committee-bounces at haskell.org> *On Behalf Of *Iavor Diatchki
>> *Sent:* 18 December 2018 18:02
>> *To:* ghc-steering-committee <ghc-steering-committee at haskell.org>
>> *Subject:* [ghc-steering-committee] Discussion for #158 "Add `setFild`
>> to `HasField`"
>>
>>
>>
>> Hello,
>>
>>
>>
>> let's start the discussion on proposal #158.
>>
>>
>>
>> After some discussion on the pull request the proposal was changed, so
>> that instead of adding another method, it now proposes to remove the
>> existing method `getField`, and add a new method `hasField`, which allows
>> to both access and change the value of a field.  After the proposal the
>> class would look like this
>>
>>
>>
>> -- `x` is the name of the field, `r` is the type of the record, `a` is
>> the type of the field
>>
>> class HasField x r a | x r -> a where
>>
>>   hasField :: r -> (a -> r, a)
>>
>>
>>
>> In addition, we'd provide two functions `getField` and `setField` which
>> are defined in terms of `hasField`.    The proposal may break existing
>> code, if it defines manual instances of `HasField`, however, code that just
>> uses the functionality will continue working as before.   `HasField` is
>> relatively new, and there aren't many reasons to define custom instances of
>> it, so it is expected that breaking code would not be a big issue.
>>
>>
>>
>> This seems like a reasonably simple change, that adds new functionality,
>> so I recommend that we accept the change.
>>
>>
>>
>> -Iavor
>>
>> _______________________________________________
>> ghc-steering-committee mailing list
>> ghc-steering-committee at haskell.org
>> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-steering-committee/attachments/20190115/141a00a8/attachment.html>


More information about the ghc-steering-committee mailing list