TDNR without new operators or syntax changes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: TDNR without new operators or syntax changes

Evan Laforge
On Sat, May 28, 2016 at 3:13 AM, AntC <[hidden email]> wrote:

>> Evan Laforge <qdunkan <at> gmail.com> writes:
>
>> ... what would happen if you tried to do records
>> just like C structs?  So e.g. a•b requires 'a' to be a record with a
>> 'b' field, and is just one identifier, no functions involved, and 'b'
>> is not a separate value.
>
> Hi Evan, um, that's the original TDNR isn't it?
> http://hackage.haskell.org/trac/haskell-prime/wiki/
> TypeDirectedNameResolution
> As per Jeremy's ref in the first post in this thread.
>
> If you're talking C then that blobby thing between a and b
> should be a dot(?) as postfix operator.
> And it is an operator, not "just one identifier".

That's why I was trying to emphasize "not an operator".  TDNR is
complicated is because the field name is a first class value, so it's
a function applied to a record, and now we have to disambiguate the
function.  I didn't meant that.

I guess C (and Java and all the others) does call "." an operator
because it parses as one and has precedence, but it works with
identifiers, not values, and has special grammar.  It's not an
operator from the haskell point of view.  The C compiler isn't doing
any overloading or disambiguation.  As far as I understand it the
implementation is straightforward.  Could ghc do something similarly
straightforward?  It already does for qualified module names, and in
the same way in M.a, ".a" is not a function that gets something out of
an M.
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: TDNR without new operators or syntax changes

AntC
> Evan Laforge <qdunkan <at> gmail.com> writes:
>
> That's why I was trying to emphasize "not an operator".
> TDNR is complicated because ...

>> Peter voldermort writes:
>> A slightly more refined definition for disambiguation: ...

Hi Evan, Peter, (and even James),

I'm not seeing you're proposing anything that's significantly different
to DuplicateRecordFields. That has the advantage we can use it now.

If you are proposing something different, you need to explain
in a lot more detail, so that we can see the advantages.

So [ref Evan] even though a field name is a first-class function usually,
DuplicateRecordFields only gets triggered where you use the bare name.

[Ref Peter] I'm not seeing why you're talking about two passes,
but that does not sound like a robust approach.
(Can you be sure two passes is enough?
 If it is enough, why can't the second pass's logic
 get built into the first?)

Yes DuplicateRecordFIelds is a bit of a hack.
The proper solution (MagicTypeClasses) is still awaited.

Can you explain why GHC should depart from that plan?


AntC

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: TDNR without new operators or syntax changes

Jonathon Delgado
AntC wrote
I'm not seeing you're proposing anything that's significantly different
to DuplicateRecordFields. That has the advantage we can use it now.

If you are proposing something different, you need to explain
in a lot more detail, so that we can see the advantages.

So [ref Evan] even though a field name is a first-class function usually,
DuplicateRecordFields only gets triggered where you use the bare name.

[Ref Peter] I'm not seeing why you're talking about two passes,
but that does not sound like a robust approach.
(Can you be sure two passes is enough?
 If it is enough, why can't the second pass's logic
 get built into the first?)
DRF only works for records, but brings polymorphism, duplicate definitions in the same module, and other goodies. This proposal will work for any function, but only helps with disambiguation. There is some overlap, but it is a different solution for different requirements.
Reply | Threaded
Open this post in threaded view
|

ORF for fields of higher-ranked type [was: TDNR without new operators or syntax changes]

AntC
In reply to this post by AntC
> Adam Gundry writes:
> ... Having spent more time thinking about record field overloading
>  than perhaps I should, ...

Thanks Adam, another thing on the back burner ...

The earlier design for SORF tried to support higher-ranked fields.
https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/SORF

That had to be abandoned,
until explicit type application was available IIRC.

We now have type application in GHC 8.0.

Is there some hope for higher-rank type fields?

AntC



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: ORF for fields of higher-ranked type [was: TDNR without new operators or syntax changes]

Adam Gundry-2
On 15/06/16 04:29, AntC wrote:

> ...
>
> The earlier design for SORF tried to support higher-ranked fields.
> https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/SORF
>
> That had to be abandoned,
> until explicit type application was available IIRC.
>
> We now have type application in GHC 8.0.
>
> Is there some hope for higher-rank type fields?

Unfortunately, doing ORF with higher-rank fields is a bit of a
non-starter, even with explicit type application, because the
combination would break bidirectional type inference and require
impredicativity. This was part of the reason we ended up preferring an
explicit syntactic marker for ORF-style overloaded labels.

For example, consider this (rather artificial) type:

    data T = MkT { foo :: ((forall a . a -> a) -> Bool) -> Bool }
    -- foo :: T -> ((forall a . a -> a) -> Bool) -> Bool

Suppose `t :: T`. When type-checking `foo t (\ k -> k k True)`, the
compiler will infer (look up) the type of `foo` and use it to check the
types of the arguments. The second argument type-checks only because we
are "pushing in" the type `(forall a . a -> a) -> Bool` and hence we
know that the type of `k` will be `forall a . a -> a`.

Now suppose we want to type-check `#foo t (\ k -> k k True)` using ORF
instead. That ends up deferring a constraint `HasField r "foo" a` to the
constraint solver, and inferring a type `a` for `#foo t`, so we can't
type-check the second argument. Only the constraint solver will figure
out that `a` should be impredicatively instantiated with a polytype. We
end up needing to do type inference in the presence of impredicativity,
which is a Hard Problem.

There is some work aimed at improving GHC's type inference for
impredicativity, so perhaps there's hope for this in the future.
Explicit type application makes it possible (in principle, modulo
#11352) for the user to write something like

    #foo @T @(((forall a . a -> a) -> Bool) -> Bool) t (\ k -> k k True)

although they might not want to! But the ramifications haven't been
fully thought through, e.g. we'd need to be able to solve the constraint

    HasField T "foo" (((forall a . a -> a) -> Bool) -> Bool)

even though it has a polytype as an argument.

Sorry to be the bearer of bad news,

Adam


--
Adam Gundry, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
12