On 13 Sep 2009, at 4:33 pm, Andre van Tonder wrote:

> The issue you raise, of how the syntactic tower should work,
> is entirely orthogonal from the REPL issue.  The above can be made
> to work or not in a REPL depending on your chosen model of
> syntactic tower.

FWIW, I did some preliminary work in my undergraduate final-year
project about handling macro-expansion in a manner that avoided these
phase-distinction problems, by imagining the semantics of the program
as being that of an interpreter that did macro-expansion "as it
went" (eg, eval starts by checking if the form starts with a symbol
that happens to be bound to a macro in the lexical environment, and if
so, expanding it, then recursing on the result). However, I never
implemented that interpreter - but I wrote a partial evaluator for a
Lisp dialect with these semantics, which walked the source code,
tracking a lexical environment as it went, replacing any symbols bound
to constants with the constants, and performing any application (I
avoided I/O and mutation, to make it easy, but they can just be
explicitly made to be ignored by the partial evaluator) where
everything in the parens was known, and expanding macros as it went.
This meant that the simple low-level macro system I threw together
(unhygienic in my prototype, but that's not inherent in the approach)
worked by virtue of the fact that macroexpander and its arguments (the
macro form) were all known at partial-evaluate time, so the whole
thing could be reduced away to the resulting form, and then
recursively processed.

Since macros and values all got propagated down the same lexical
environment during the pre-processing phase, you could write (the
equivalent of) a series of nested let and let-syntax forms, each
referring to anything from an outer let or let-syntax, without any
trouble. In particular, you could define (say) a bunch of functions
for doing matrix arithmetic, then some macros that optimised matrix-
arithmetic expressions by knowing some useful invariants; both the
macro-expander and the resulting expanded code could refer to the
matrix arithmetic functions from the enclosing lexical scope without
any nasty define-for-syntax trickery.

It all revolved around immutable bindings, but it could be made to
happen in a language more like Scheme by some kind of replacement of
mutable bindings with boxes, and marking primitive functions that do I/
O or mutate state or access mutable state as not to be partially-
evaluated; however, analysing the bindings to find out which are
subject to set! *before* expanding the macros would be tricky, as a
macroexpansion may result in a set!, but you couldn't do the partial
evaluation (which heavily relies on being able to inline symbol
references) until all your bindings are immutable.

ABS

--
Alaric Snell-Pym
Work: http://www.snell-systems.co.uk/
Play: http://www.snell-pym.org.uk/alaric/
Blog: http://www.snell-pym.org.uk/archives/author/alaric/




_______________________________________________
r6rs-discuss mailing list
[email protected]
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss

Reply via email to