
Will such a preprocessor work on source code like cpp does or on a syntax tree? The latter would be better, IMO; the former would probably have little or no advantage over cpp.
A bunch of people have answered this already but your comment reminded me of one of the cpp problems we might want to avoid (by omitting a large chunk of cpp functionality). One of cpp's flaws is that it has absolutely no notion of scope so if you define a macro 'bar' then code like this can do surprising things. foo bar = baz What do people use macros for? 1) Aliases and abstraction: Macros are useful in C because C is quite poor at defining aliases for existing things. (e.g., typedefs can't be parameterized, you can't define an alias for a variable, creating an alias for a function is expensive unless you (can) mark it inline). Haskell has great ways of creating aliases for things: type synonyms and function definitions. There's no strong need for more. (A few exceptions listed at the end of this mail.) 2) Defining symbols to be used in #ifs This is useful for conditional compilation in both C and Haskell. So, I'd like to float the idea that the Haskell preprocessor should _only_ support conditional compilation, that macro expansion should only occur in lines that begin with '#' not in "normal" lines and that macros should always evaluate to expressions with simple scalar types (ints, strings, etc.) Similarly, I'd like to drop token splicing (e.g., foo##bar in ANSI C or foo/**/bar in K&R C). It's mostly useful for overcoming limitations in C and isn't much used to help you write #ifs. These two changes make it possible to replace the usual horrible mix of macro expansion, parsing and evaluation with a conventional interpreter. #defines assign values to variables and #if evaluates expressions involving those 'variables'. I'm not sure if it would still be useful to be able to define parameterized macros like #define max(x,y) ... but I doubt it would cost much to allow it. Advantages: 1) hspp implementation is a lot simpler. [It's probably simple enough that the preprocessor could easily be built into Hugs if we wanted. This isn't the primary motivation for this suggestion but it would be nice.] 2) hspp semantics easier to understand so programmers not caught out by name capture and all the other problems that cpp can cause. 3) hspp only affects lines that start with # in the first column. This further lessens chance of programmer being caught out. 4) No need to add extra parentheses round every use of a macro argument and round macro bodies as in: #define max(x,y) ((x)>(y)?(x):(y)) There's only one place I know of where this restriction would have any significant effect. The FFI libraries have a lot of very similar definitions for all the new FFI types to define the Storable instances. IIRC, a cpp macro is used to significantly reduce the amount of code that has to be written and to make it easier to read/maintain. It would be a shame to lose this use of cpp but, if this is the only loss, I think it would be worth it. -- Alastair Reid www.reid-consulting-uk.ltd.uk ps Inessential syntax tweak: If we are willing to change cpp syntax instead of just restricting it, we might require "=" between the lhs and rhs of a macro definition. This makes parsing of macros a little easier. cpp macros are a bit funny in that you get very different results if you write a space between the macro name and the arguments. For example: #define max(x,y) x>y?x:y and #define max (x,y) x>y?x:y The first is a parameterized macro, the other isn't. With this change, the following would be equivalent. #define max(x,y) = x>y?x:y and #define max (x,y) = x>y?x:y