[ghc-steering-committee] Proposal #606: small syntax change around types in terms; recommendation: vote

Adam Gundry adam at well-typed.com
Thu Jan 25 08:25:17 UTC 2024


On 25/01/2024 06:14, Moritz Angermann wrote:
> Maybe I'm misreading this, but this can potentially break existing code, 
> can it not?

I don't think this has been released yet, because RequiredTypeArguments 
is coming as part of GHC 9.10, and the fork is due in about a month. So 
there's no existing code to break and we can freely choose at this 
point, provided the decision is made in good time. Of course if 9.10 
ships with option 1 and we later switch to option 2, that would be a 
breaking change. But it looks like HEAD might currently have option 2 
implemented anyway?

As to the proposal overall, I'm rather on the fence.

Adam



> On Thu, 25 Jan 2024 at 02:47, Richard Eisenberg <rae at richarde.dev 
> <mailto:rae at richarde.dev>> wrote:
> 
>     Proposal #606
>     <https://github.com/ghc-proposals/ghc-proposals/pull/606> has been
>     submitted to the committee, by Vlad.
> 
>     This proposal makes a tiny change. Suppose we have `f :: forall (x
>     :: Type) -> x -> ...` (this is part of -XRequiredTypeArguments).
>     Then (as proposed) we can write `y = f (type Int -> Int) abs ...`.
>     The `type` keyword here is to signal that what comes is a type: it
>     should be parsed as a type and name-resolved as a type. This might
>     matter if there is, say, a constructor Int in scope. The proposal at
>     hand is whether to accept the above program or to require extra
>     parentheses, thusly: `y = f (type (Int -> Int)) abs ...`. That's it
>     -- that's the entire proposal. (It says we should _not_ accept the
>     former, without parentheses.)
> 
>     The motivation is to avoid surprising users. Normally when we have
>     `word1 word2 -> word3`, word1 and word2 will associate more closely
>     than the arrow. Yet the first example has `type Int -> Int` where
>     the arrow binds more tightly. Because `type` is a keyword, this is
>     no challenge to parse and is not ambiguous -- it's just perhaps
>     confusing to users.
> 
>     There was some debate in the proposal, but in my perusal, not a
>     clear indication toward any particular direction. The most rigorous
>     statement I could find is that the new syntax is a subset of the
>     original, and so we can easily reverse this decision later.
> 
>     I propose we vote on the matter. We have two choices:
> 
>     1. Original syntax: allow `(type Int -> Int)` as an argument.
>     2. Amended syntax: require `(type (Int -> Int))` as an argument.
> 
>     --------------------------------
> 
>     My vote: 1.
> 
>     There are many keywords in Haskell, and we are used to parsing these
>     differently. For example, if we have `f (do x <- blah ...)`, we know
>     quite well that the <- is within the `do`, not the other way around.
>     Ditto `case`: we don't require scrutinees to be parenthesized. I
>     posit that the strangeness some have felt around `(type Int -> Int)`
>     is (understandable) confusion in the face of novelty. But the `type`
>     herald will not be novel forever, and I think we'll enjoy having
>     fewer parentheses in our code in the long run. (I might be arguing
>     for "2 today, then 1 tomorrow". But let's just skip the intermediate
>     step and do 1 now.)
> 
>     I welcome your opinions and votes. It would be great to conclude
>     this in the next 2 weeks, by Feb 7.
> 
>     Thanks!
>     Richard


-- 
Adam Gundry, Haskell Consultant
Well-Typed LLP, https://www.well-typed.com/

Registered in England & Wales, OC335890
27 Old Gloucester Street, London WC1N 3AX, England



More information about the ghc-steering-committee mailing list