On 18/11/13 01:36, Vassil Nikolov wrote:
> I am not advocating fexprs at all, just
> pointing out various aspects of having
> them in a language.
An entertaining thought experiment indeed!
When I were a young lad, back at the turn of the last millenium, I
tinkered with a macro system for a Scheme-like language. I labelled it
"second-class macros", as they weren't *quite* first class, but almost so.
The idea is that you have an fexpr-like semantics, where macros are
values somewhat like procedures. The macro expander was based around
partial evaluation, doing large amounts of constant propagation and
inlining at compile time. It would try and propagate these second-class
macros into the first elements of applications, and then "inline the
macro", actually evaluating it with the supplied s-expressions to get a
new s-expression to replace the macro call site with. This was fairly
similar code to inlining a procedure call! In the meantime, it would
also be aggressively propagating and inlining all sorts of other kinds
of values, too.
And the rule that made the macros second-class was that no macro values
could remain in the input to the compiler once macro expansion was
complete. In other words, all expressions that computed macros
(generally in order to "apply" them, as they're not much use otherwise)
had to be computable at compile time.
So you could write "((if x a b) y z)" to choose which of two macros, a
or b, to use; and as long as x could be reduced to a literal at compile
time, that was JUST FINE. But if it couldn't, then the output of the
expander would still include a and b (no longer just the symbols, of
course, but the propagated actual macro values), and it'd be rejected by
the compiler.
This was all good fun, and easy enough to do in a pure functional
dialect of Scheme (mutation really bungs up the kind of aggressive
constant propagation and inlining I was doing), but would be hard to
scale to a Scheme with mutation!
I speculated a little about making the semantics more complete by
allowing macros to persist to run time, by embedding an interpreter and
a compiled representation of the lexical environment and all that, and
handling applications of macros at run time by expanding the macro and
then evaluating the results; but I didn't think very much of the idea...
ABS
--
Alaric Snell-Pym
http://www.snell-pym.org.uk/alaric/