
Brandon Allbery wrote:
On Wed, Apr 16, 2014 at 2:42 AM, Kazu Yamamoto
wrote: If ghc-clang-wrapper causes problems with your code, I'd suggest to fix your code. I'm not sure this actually happens.
It does. See my previous messages. Haskell is not C, and some Haskell constructs simply will not work with a program that must lex (and, for ANSI, parse) C code.
I agree that ghc-clang-wrapper can cause problems and GHC should provide its own CPP. But have you ever experienced such problems actually?
I personally have not, but that's largely because I haven't really ever needed to use -XCPP. I did earlier today talk with someone on IRC who was running into one lexical incompatibility (Haskell's allowing ' to be an identifier character), and have in the past helped diagnose issues with the clang wrapper not working with some programs on Hackage which are incompatible with ANSI C (that ' issue, plus the use of # and ##).
And I consider it nonsensical that people who need to use -XCPP to deal with different library versions or language extensions are restricted to that subset of Haskell which is lexically compatible with C. The problem here is not those people's code; it is that we are relying on a tool which by its nature lexes C code, and using it on Haskell code.
I couldn't agree more. My experience in this area is very bad. I am maintaining a language that is very C-like (it has *almost* the same lexical syntax), and still I regularly encounter problems when CPP is used as a preprocessor for it, due to sudden changes that are made e.g. by the GNU folks that are compatible with C but not other languages. Furthermore, I strongly suggest that a suitable replacement for CPP should be designed in such a way that its specification can be added to a future Haskell language standard. This is the only way to ensure that implementations other than GHC can be brought along. Has nobody ever written a paper about how to extend Haskell with the few features we actually need from CPP? I think general macro replacement like CPP offers is not on the list, right? IIUC, CPP is used in Haskell libraries almost exclusively for conditional compilation. I think the syntax should be based on pragmas, like in {-# DEFINE WITH_FEATURE_X True #-} {-# IF WITH_FEATURE_X && GHC_VERSION >= 708 && GHC_VERSION < 712 #-} ... {-# ELSIF <some other condition> #-} ... {-# ENDIF #-} That's four new pragmas (IF, ELSIF, ENDIF, DEFINE). Expressions (in DEFINE, IF and ELSIF) must have type Bool (True, False) or Integer (decimal notation only), identifiers must be ASCII (letter, followed by any amount of '_' or letter or decimal). Writing an evaluator for such expressions is an exercise for beginners. There is no need for such a CPP-replacement to be able to parse (nor even lex) all of Haskell; it just needs to understand lexing of Haskell string literals (so a pramga inside a string literal gets ignored) and comments. (Hmm, what about TH splices?) Existing Haskell implementations like GHC are of course free to integrate the preprocessing stage with normal compilation, making implementation even simpler. It's all very simple and nicely integrated. It would even be possible to write a tool that automatically converts existing Haskell modules that now use CPP directives to the new style (assuming the above is really the subset of CPP features that is actually used in practice). Cheers Ben -- "Make it so they have to reboot after every typo." -- Scott Adams