[gambit-list] Black hole documentation
Per Eckerdal
per.eckerdal at gmail.com
Sun Jul 12 14:42:06 EDT 2009
> Hi Per,
>
> First question I have is :
>
> Can you elaborate on why you decided to model black hole on
> syntax-rules vs other approaches like R6RS syntax-case for instance.
> My knowledge of those approaches is very light but it seems that if
> R6RS decided to scrap syntax-rules and go for another approach there
> must be good reasons. Can you comment on that? It would help a lot in
> getting an idea of the strengths and weaknesses of black hole.
>
> Also, I read that syntax-rules doesn't support any kind of
> non-hygienic macros. Is that the case for black hole or did you extend
> it to support non-hygienic macros?
-- First, my thought about syntax-rules vs. syntax-case
It's true that syntax-rules doesn't support any kind of non-hygienic
macros. All variables that the macro uses must be passed explicitly as
parameters to the macro. I have not made any extension to this kind of
macro. BH does not even support SRFI-46, but that should be really
simple to implement when needed.
The reason I wanted to support syntax-rules are mostly pragmatic; I
wanted to be able to use other people's R5RS code. Also, I wanted to
make it easy for people who are writing code in Black Hole to write it
in a reasonably portable way.
Syntax-rules macros are based on pattern matching, and are turing
complete. However, many useful operations that are possible to do in
Scheme are impossible to do in syntax-rules macros; string operations
for instance.
In essence, syntax-rules is a tool for writing macros that is easy to
learn and it's easy to write correct macros in it. Most macros are
very simple, and syntax-rules excels in those cases. My impression is
that syntax-rules was put in R5RS without very much thought, but it
was still in many ways an improvement over R4RS macros (non-hygienic,
I think). R5RS' specification of syntax-rules is rather hairy at
corner cases, and implementations claiming full R5RS compliance often
have slightly different behavior.
But, syntax-rules macros are 1) not able to break hygiene in any way
2) not able to execute arbitrary Scheme code. Syntax-case is, as I
understand it, but honestly, I don't know very much about syntax-case,
able to do both of these things. It seems people who don't like R6RS
often criticize syntax-case for breaking the principle of lexical
scope, and for being overly complex.
-- How this relates to Black Hole
Black Hole's macro system is not modelled on syntax-rules, it is based
on syntactic closures, and syntax-rules is implemented in terms of
syntactic closures. Implementing syntax-rules took only about a day,
and it should be possible to implement syntax-case as well. I just
haven't done it.
Chicken's macro system is based on explicit renaming, which might
actually be a better choice than syntactic closures, because I have
heard that ER is faster than SC, not sure though. So far, I haven't
had any performance problems, but I am going to have to change a
rather large part of the hygiene core to be able to implement let-
syntax properly, and that might make it slower. (At the moment, it's
not always possible to use define-syntax directly inside let-syntax)
The reason I chose syntactic closures over explicit renaming is that I
think it's easier to write SC macros than explicit renaming macros.
Also, I would guess that it's easier to implement syntax-rules in SC
than in ER. SC is basically a little bit higher level than ER.
There is one more thing that I ought to mention. Because syntax-rules
doesn't allow execution of arbitrary code, syntax-rules is very
convenient for the module system/compiler/interpreter writer. Allowing
execution of arbitrary code introduces all kinds of strange problems,
and the only really good solution to those problems that I know of is
called the syntactic tower. The syntactic tower requires all modules
to have a potentially unbounded number of instances; one for each
compilation phase (run-time, compilation time, compilation-compilation
time, and so on). Implementing this is rather tricky if you want to do
it efficiently.
At the moment, BH does not implement the syntactic tower; there is
only one set of globals. Because of this, macros using global state
become quite fragile. That's why syntax-rules is the recommended way
of writing macros; it's impossible to run into these problems if you
use them. Also, if you need more powerful macros, you can always use
sc-macro-transformer (syntactic closure macros).
I have found a way to implement the syntactic tower in a way that
doesn't inhibit the performance of the code after it's macro expanded,
but it's somewhat complex and I haven't found the time to do it yet.
It's rather high on the to do list though.
/Per
More information about the Gambit-list
mailing list