Opened 5 years ago

Closed 5 years ago

#9515 closed feature request (wontfix)

Deprecate -XExplicitForAll

Reported by: dfeuer Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.8.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

The problem is that it uses the same syntax as -XScopedTypeVariables to mean something a bit different, and incompatible. -XExplicitForAll is of rather limited utility, whereas -XScopedTypeVariables is a wonderful thing. Confusion is bad.

f :: forall a . a -> [a]
f a = let g :: a -> a
          g x = x
      in g [a]

Change History (16)

comment:1 Changed 5 years ago by simonpj

Good idea. So far as I can see the sole effect of -XExplicitForAll is to enable the forall keyword. It's implied by RankNTypes, ScopedTypeVariables, LiberalTypeSynonyms, ExistentialQuantification.

I'm all for deprecating it as a flag in its own right. Does anyone want to offer a patch? Need to update the user manual too, and get rid of uses of it in the GHC tree itself.

Simon

comment:2 Changed 5 years ago by kosmikus

If the idea is to avoid confusion, and the ExplicitForall flag is currently implied by others, then shouldn't RankNTypes, LiberalTypeSynonyms, and ExistentialQuantification all imply ScopedTypeVariables instead? But that's somewhat non-obvious ...

I personally think that while the current situation is unfortunate, the proposed solution isn't ideal either. I'd keep everything as it currently is, until we get to a point where we can agree that ScopedTypeVariables should be enabled by default.

comment:3 in reply to:  2 Changed 5 years ago by dfeuer

Replying to kosmikus:

If the idea is to avoid confusion, and the ExplicitForall flag is currently implied by others, then shouldn't RankNTypes, LiberalTypeSynonyms, and ExistentialQuantification all imply ScopedTypeVariables instead? But that's somewhat non-obvious ...

I personally think that while the current situation is unfortunate, the proposed solution isn't ideal either. I'd keep everything as it currently is, until we get to a point where we can agree that ScopedTypeVariables should be enabled by default.

I think it would be great if ScopedTypeVariables (or conceivably something even better) were eventually implied by others, or even if it came to be the default behavior in the next Report. I think the first step in any case has to be phasing out the formally useless ExplicitForAll; once it's sufficiently dead, that syntactic space will be entirely free for a more useful replacement. You were wise to note the problem that ExplicitForAll is currently implied by other flags; I think the interim solution is to add a warning when those flags are used without ScopedTypeVariables: "XxxxXxxxxx currently implies ExplicitForAll, which is deprecated. To avoid this warning, add ScopedTypeVariables and rename type variables as necessary."

comment:4 Changed 5 years ago by dfeuer

I've gone over practically the entire GHC source tree (I ran out of time before I could look at the last few validation test files).

Good News

Very few files explicitly use ExplicitForAll.

Of all the files that use ExplicitForAll or anything that implies it, only one, a file in the fibon benchmark suite, would need minor changes to work with ScopedTypeVariables.

Bad News

Lots and lots of files use extensions that imply ExplicitForAll and don't use ScopedTypeVariables.

I don't personally see an obvious way to warn when something implying ExplicitForAll is used without ScopedTypeVariables, although someone else may be able to figure something out.

Question

Should we just bite the bullet and just make everything that currently implies ExplicitForAll imply ScopedTypeVariables instead? It seems, contrary to my earlier fears, that this is likely to break very little real code.

Last edited 5 years ago by dfeuer (previous) (diff)

comment:5 Changed 5 years ago by isaacdupree

Yes, bite the bullet! I'm one of the people who initially advocated for ExplicitForAll (https://www.mail-archive.com/haskell-prime@haskell.org/msg02765.html).

+ It sounds like the semantic inconsistency between "forall" with and without ScopedTypeVariables is annoying

− The downside is a hypothetical Haskell compiler that wanted to implement, say, RankNTypes but not ScopedTypeVariables would be stuck

Seems to me that the plus is more important than the minus in today's Haskell world.

comment:6 Changed 5 years ago by simonpj

Specifically, apart from -XScopedTypeVariables, the following flags imply -XExplicitForAll:

  • -XRankNTypes
  • -XLiberalTypeSynonyms
  • -XExistentialQuantification

So the concrete proposal is:

  • Abolish -XExplicitForAll
  • Make the above three flags imply -XScopedTypeVariables, which in turn would switch on the forall keyword, and make type variables have lexical scope.

I would be fine with this. I'd like to hear more opinions.

Simon

comment:7 Changed 5 years ago by nomeata

I’m slightly worried that we’d breaking some code for little gain.

I am accustomed to read type signatures as a local, self-contained thing, unless ScopedTypeVariables is on – what’s wrong with keeping that behaviour?

comment:8 Changed 5 years ago by carter

I'm inclined to agree with Nomeata. Or at least, A survey of how this would impact code that's currently buildable on hackage would be needed to accurately evaluate the scope of the impact.

comment:9 Changed 5 years ago by dfeuer

This only affects code that does something a bit strange. In particular, it has to use a forall in an outer position (not for a higher-rank type or an eqxistential) and it reuse the same type variable without a new forall. I'd be happy to participate in a survey of Hackage code, but I'm not sure how to go about that—there are thousands of files on Hackage.

comment:10 Changed 5 years ago by goldfire

I'm -1 on this, along the same lines as nomeata. I think it would be unexpected to have, say, ExistentialQuantification imply ScopedTypeVariables. If there were a clear upside, I would back off, but I don't see a compelling reason to do this.

comment:11 Changed 5 years ago by nomeata

I'd be happy to participate in a survey of Hackage code, but I'm not sure how to go about that—there are thousands of files on Hackage.

I’d recommend looking at stackage, which has a collection of packages that compile with each other, and ways to run it (haven’t done that myself yet, though).

comment:12 Changed 5 years ago by isaacdupree

We could change ExplicitForAll to be a subset of ScopedTypeVariables. Make "forall" always introduce type variable scopes, but error if any type variable is actually used in a scoped way without ScopedTypeVariables.

(I am not volunteering to implement that change - I don't feel strongly enough about this)

comment:13 Changed 5 years ago by carter

whats missing is a good motivation for why we need do this breaking change. (ie whats the merits and demerits)

comment:14 Changed 5 years ago by rwbarton

FWIW I don't regard ScopedTypeVariables as changing the semantics of forall. Rather it changes the meaning of type variables in type ascriptions and non-top-level type declarations depending on whether those variables were mentioned in a particular syntactic form involving forall. As such I don't experience any cognitive dissonance when thinking about ExplicitForall, RankNTypes, ScopedTypeVariables, and their various combinations.

I realize that this is a subtle distinction and that ScopedTypeVariables is often described as bestowing a special new meaning on the keyword forall.

comment:15 Changed 5 years ago by simonpj

The easiest thing to do is...nothing. That will not break anyone's code. I agree it might be neater to do something else, but it seems to be causing more trouble than it's worth.

Simon

comment:16 Changed 5 years ago by dfeuer

Resolution: wontfix
Status: newclosed

It seems clear this is too controversial, at least for now, so I'll clear it off the table.

Note: See TracTickets for help on using tickets.