In terms of implementation, it wouldn't be hard to restore the old behavior of @, but it would violate a nice law stated in the proposal:
A loose infix occurrence should always be considered an operator.
Personally, I feel that there must be a very strong reason to add a side condition such as this:
A loose infix occurrence should always be considered an operator (except for @).
Adherence to the Haskell Report cannot be a reason in this case, because the entire point of the proposal is to diverge from the report in case of ~ and !.
Initially it didn't affect @ or $, but later I was asked to generalize the specification, and I think it was the right call.
Anyway, I see this is not gonna be reverted. But it shouldn't be released if the parser error is of this low quality:
Prelude> let pairs xs @ (_:xs') = zip xs xs' in pairs [1,2,3]<interactive>:4:5: error: Parse error in pattern: pairs
I want to remind that patches were reverted because they started to reject previously accepted programs with hard to understand errors. This is exactly that situation.
No (and have no ambition to join it any time soon). I just meant that I would provide the same arguments against it in the GitHub discussion as I provided here.
it shouldn't be released if the parser error is of this low quality
Would it be possible to detect that the parse error is in an expression containing a bare @, and issue a more precise diagnostic error? [ Yes, that carries most if not all of the cost of supporting whitespace around @... :-( ]
@phadej Do you think that would be enough to make the error message acceptable? If so, do you have any suggestions about the exact phrasing of the error message?
Any improvement (and hint how you might repair it) in error message is in improvement.
I realised that GHC parser is quite terrible at error messages in general.
So I would be happy be with literally any improvement. See:
GHCi, version 8.11.0.20200527: https://www.haskell.org/ghc/ :? for helpPrelude> [| foo |]<interactive>:1:2: error: parse error on input ‘|’Prelude> proc x -> id -< x<interactive>:2:8: error: parse error on input ‘->’Prelude> id @Int<interactive>:3:4: error: Variable not in scope: (@) :: (a0 -> a0) -> t0 -> t<interactive>:3:5: error: Data constructor not in scope: IntPrelude> let foo :: forall a. a -> a; foo x = x<interactive>:4:12: error: Illegal symbol ‘forall’ in type Perhaps you intended to use RankNTypes or a similar language extension to enable explicit-forall syntax: forall <tvs>. <type>
I guess that's because forall is always a keyword, and proc isn't. Yet [| cannot be anything in valid Haskell98, can it?
As you can notice from above, the @Int error has regressed. Even in ghc-8.0.2:
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for helpPrelude> id @Int<interactive>:1:1: error: Pattern syntax in expression context: id@Int Did you mean to enable TypeApplications?
and if you do something silly like:
GHCi, version 8.11.0.20200527: https://www.haskell.org/ghc/ :? for helpPrelude> let (@) = ($)Prelude> id @Int<interactive>:2:5: error: Data constructor not in scope: Int
i.e. have @ in scope (but no -XTypeApplications) confusion is guaranteed.
I think that @ should stay as reserved-op, that would allow making better error messages.
I agree with our current handling of whitespace, and I'm glad that we see a way forward to improving the error message. I suppose no one is clamoring for making @ unreserved, so we could reverse that decision. I don't feel strongly either way.