Re: CPP and system configuration
from Simon Peyton-Jones on Mon, 4 Oct 1999 03:17:12 -0700)
Subject: Re: CPP is not part of Haskell
--text follows this line--
I'm not sure I agree with this. Keith Wansbrough has an
paper that identifies the ways in which a macro processor can
do thing that ordinary functions can't. One solution is to add
macros (presumably in a more hygienic form than cpp), but I'm
to advocate that, because macros undoubtedly do overlap with
So I'm waiting and hoping that someone will have a Really Good
(And using cpp meanwhile.)
All right, I'll take the bait.
All the proposed solutions I have seen float by so far are hacks:
quick to implement, simple to learn, limited power. Some have even
said the lack of power is a virtue. This seems short-sighted to me.
So I'm going to sketch a longer term solution that should be much more
powerful, much cleaner, and of course, correspondingly more difficult
to implement. I don't think it will solve the problem of legacy code,
that Lennart Augustson pointed out, but I imagine it would eliminate
problems for all current code on forward.
I have a particularly vested interest in this solution, because it
should do much more for Haskell than setting compilation options. I
really want to have better languages for implementing interactive
systems, and I'm turning into a zealot for that cause, mostly because
it turns out I'm not very good at doing the language design and
development myself. So I've decided to proselytize instead.
The most important thing is to realize that we are discussing
computations that need to be done at compile time. The results affect
the body of the source code. Right now, the source code is
effectively required to be constant. If we think in good functional
programming terms, we want to have the source code be the result of
This implies that we need a language to describe the computations over
source code. CPP or any of its ilk is simply not a good long term
solution here. CPP is a good short-term hack, nothing more.
So, what's our choice of language? Well, we already have one
language, of course. Haskell. Rather than invent a new one, we
should investigate whether the current one is appropriate. So, is
Haskell well suited to the job?
The answer is no, not as it stands. Haskell is structured as a
typical batch-oriented language. Rich syntax, lots of features, like
overloading, but no features of the kind like one finds in most shells
and scripting languages, e.g., constructing expressions through symbol
and string manipulation.
But there is at least one ongoing research project on a related
subject. Tim Sheard and Walid Taha built MetaML, where one can create
parameterized code just by adding a few angle brackets. Furthermore,
Paul Hudak told me Tim was at Yale last year working on adapting the
MetaML techniques to Haskell/Hugs.
I haven't had time to study their system in depth yet, but it seems to
me that code configuration is a subset of it's capabilities. Here's
what I think it would take to make a good configuration system.
1) A module with variables and functions that model the computing
environment, e.g., processor type, OS type, etc.
2) MetaHaskell higher-order code manipulation functions.
3) A partial evaluator that understands how to work with the
higher-order code, and that also understands which of the variables
and functions of part (1) have static bindings when compiling a
program and dynamic bindings when run in an interpreter.
The point of 3) is that a partial evaluator would be able to optimize
out many of the conditionals in a compiled program, e.g., processor
dependencies, because the processor type for a compiled program is
constant. For an interpreted program, the processor is not constant,
and so the meta code should be executed at run time. Furthermore,
using a multi-stage binding approach, values that are not fixed at
compile time, but which may be static throughout the program's
execution, could be handled with polyvariant and/or template filling
methods. For example, if the program supports two different graphics
libraries, that could be determined at the beginning of the program
execution, and optimized wrappers for that library would be used.
These code manipulation functions are useful for other things as well,
and should become part of the normal skill set of your basic
run-of-the-mill MetaHaskell programmer, of which I'm sure there will
be millions in the near future. So system configuration would be
nothing special; programmers could use the same mechanism for both.
After all, why shouldn't we be able to right programs that adapt
themselves on the fly, make themselves as efficient as possible for a
The functional programming community has been so good at producing
good, clean, languages that are almost restful to use. Over time,
much progress has been made to bridge the gap between mathematically
interesting and practically viable. I think that this issue is one of
the biggest things remaining.
I'm not certain yet, but I think a MetaHaskell with interpreter and
compiler would become my one and only programming language, including
shell and system programming, application configuration, etc. I
haven't really done a good comparison between Haskell and ML, yet.
MetaML is the only thing I know of that comes close, and the thought
of having those capabilities is really exciting. The Scheme macros
I'm using now really make my brain hurt.
In short, I believe the tools for a really good solution, one in the
full spirit of the functional programming movement, are already there
in the existing body of research. It's clearly a longer row to hoe,
but I think the Meta support is essential anyway (I'm finishing a
thesis on exactly why), and I think it would solve the configuration
Clifford Beshers Computer Graphics and User Interfaces Lab
firstname.lastname@example.org Department of Computer Science
http://www.cs.columbia.edu/~beshers Columbia University
Post to "haskell":