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
