happy
happy copied to clipboard
Bold change: Continue supporting LR's `--array --ghc --coerce` mode, abandon the rest
The happy LR backend has 24 different modes, making it quite insane to maintain and extend. These 24 modes depend on
- whether you want to provide your own lexer or simply have a
[Token]available - whether you want to have a monadic parser
- whether you want to generate a table-based parser (
--array) or a recursive ascent parser with explicit stack (i.e., generate Haskell code, the default).--arraybased parsers tend to be introspectable (this is huge) and smaller but a bit slower. (The latter seldomly matters for an LR parser, because the language it parses will need name resolution and type checking as well.) - whether you want to target GHC (
--ghc) for using unboxed integers and bytestrings (in--arraymode)- and if so, whether you want to use
unsafeCoercefor another performance boost (--coerce)
- and if so, whether you want to use
Realistic applications only ever tend to use --array --ghc --coerce. I suggest we abandon the non-array, non-ghc modes to get down to a more manageable 4 modes, not least because it also means we can get rid of the mandatory {-# LANGUAGE CPP #-} that is currently emitted: https://github.com/haskell/happy/issues/263 Ironically, that means that even the code generated without passing --ghc is GHC dependent. Plus, I don't have any plans to make error resumption work in recursive ascent mode, because the stack unwinding necessary would need a lot of work that is entirely orthogonal to the table-based mechanism.
In general, I second this.
That should be happy-2.0 then. I'd still keep the command line options but emit a warning that these are obsolete now.
Note e.g. that the these command line options are always passed to happy by cabal: https://github.com/haskell/cabal/blob/0b34b4eaac65fb5a5ece8f7846077c4a3d627520/Cabal/src/Distribution/Simple/PreProcess.hs#L872-L879
The decision on major changes is with the primary maintainers @int-index @Ericson2314 .
I merely contribute conservatively to the current happy-1.20 at this point, not to the unreleased refactored happy on master.
For context, I proposed bringing #272 (which introduces other breaking changes around %errorhandler explist) into a mergeable state and applying the result to GHC as a GSoC proposal.
It would probably be good to fix this issue as the first action before we rebase #272 on top of it and would likely lead to simplifications of #272 in turn. For example, we could finally give accurate type signatures in the template file rather than generating them from happy only if we need them for disambiguation purposes (because it is so painful to do so).
Either way, this work would probably be bound for happy-3.0, as I think we should not hold back a 2.0 release featuring just the split packages. One breaking change after another...
What do the other maintainers think? @int-index @Ericson2314 any strong opinions? I think it would make the template files much simpler if we could just assume that it's OK to unbox integers, user coercions, etc.
It would also make the life of @Kariiem much simpler, who is the GSoC student working on happy this summer.
any strong opinions?
I feel rather strongly that we should retain the option of generating safe code without unsafeCoerce. The remaining configuration space can be reduced.
The main payload of this proposal has been implemented in #276 and #278.
One remaining question is whether we should somehow notify people of the change when they pass the obsolete -g or -a. On the other hand, people who do not pass -g or -a potentially are affected much more.
any strong opinions?
I feel rather strongly that we should retain the option of generating safe code without
unsafeCoerce. The remaining configuration space can be reduced.
I agree with that
I want to ask for feedback regarding @andreasabel's excellent suggestion
I'd still keep the command line options [for -ag] but emit a warning that these are obsolete now.
This sounds like a good idea in principle, but shouldn't we rather (or also) warn when the flags are omitted rather than when they are present? That is, we could warn
- when the flags are present, because they are slated for removal in a future release. (i.e., warn if either
-aor-gis present) - when the flags are omitted, because we now generate different code that might no longer compile on non-GHC configurations. (i.e., warn if
-gis not present)
I think (1) is what Andreas suggested, which makes sense. (2) on the other hand depends on whether we regard the payload here as a breaking change. I think we do, do we?
Then perhaps happy should always warn, for both (1) and (2)? Should we provide a temporary flag to suppress these warnings?
Well, if the final target is to remove these options, I wouldn't warn about missing -g etc. This might prompt users to add them, only to later be faced with the removal, requiring a reversal of their changes.
Of course, turning on -g silently always is a breaking change, but that could be indicated by a big version bump (plus changelog).
Well, if the final target is to remove these options,
Please don't, if it's not a must. It will make e.g. Cabal's life (and others tools which cannot only use newer happy immediately) harder (AFAIK currently Cabal doesn't care much about happy version).
Cabal always passes -g, so yes, removal would cause extra work there (and probably in tons of other user code), so keeping these options in as always on is the most backward compatible way.
For stable tools like happy one has to resist any cleanup urges.
I was toying with adding a flag --api-level=2 to silence the warning (2). But ultimately that is just like passing -ag in the first place if we never remove -ag (which I second).
So we should emit a warning if -g is not present, indicating that breaking changes are to be expected since happy >= 2.0 assumes -g (and -a, but that is rather an internal change).
#290 provides the fix. Example warning:
Warning: With happy 2.0, the --ghc flag has become non-optional. To suppress this warning, pass the --ghc flag.