[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


   From: jar@cs.cornell.edu (Jonathan Rees)
   Date: Tue, 6 Apr 93 00:04:58 -0400

   You picked about the worst possible way to add macros to your system.

Are you referring to the low-level SCM builtins:

  (procedure->syntax <proc>)				procedure
  (procedure->macro <proc>)				procedure
  (procedure->memoizing-macro <proc>)			procedure

or to the syntactic closures and syntax-case packages in SLIB?

As for the SLIB packages, I posted notices more than once asking for
portable macro packages.  I got no replies so I had to port syntactic
closures myself.  I have since then asked if anyone had a macro
package which didn't expand all the way down to primitive expressions
and also got no replies.

   For your purposes -- assuming you still really really want to stick
   with a pure s-expression interpreter --

Yes I do.  It is small and fast and it is not really pure (it modifies
Scheme expressions as it evals).  Your apparent incredulity is the
sort of comment that motivated my last message.  I think one of the
attributes that shows a language has expressive power is that it can
be implemented in various ways.  I hope that some other authors share
this view and will not write SCM out of R5RS.

   you should interleave macro
   expansion with evaluation, replace (or at least streamline) Hanson's
   overly general implementation, and retain your previous implementation
   of built-in macros like OR (unless I misremember how SCM works).

The only macro expansion SCM does to OR is to replace the symbol 'OR
with an special token #@OR (SCM bashes the CAR, so this is done only
once per occurrence).

As for interleaving expansion with evaluation, that is what I
tried to do, but I am having problems with internal defines.  In order
to find out that a macro will return DEFINE or BEGIN of DEFINEs, I
have to expand it before evaluation.  This requires an expansion
prepass which replicates the environment tree and does other work
which is already done in eval.  That is why I think that macros will
double the EVAL code.

Another possibility is to have internal defines be a SCM primitive
form.  In order for this to work, I have to be able to augment the
environment of a body without knowing if this is the first DEFINE in
the body or not.  I am investigating this but I think there are some
screw cases like (letrec ((x 3)) (define x 5) x).  If I can get this
to work, it has the additional benefit that macros can be expand-only;
I.e. I don't have to combine DEFINEs into a LETREC.

   Also, Hanson may not optimize the output of the syntax-rules macro -
   you might want to compare it to the version in pseudoscheme or
   scheme48 (both in ftp.cs.cornell.edu: pub/jar/).  I have not noticed
   any particular penalty for hygienic macros in scheme48, but then it
   does preprocess code, and I haven't done a controlled experiment.

There is not much difference in the output from the macro expanders
(syntax-case and syntactic closures) as they both output primitive
scheme expressions.  The reason this slows down SCM execution 30% is
that it doesn't allow SCM to execute the derived forms directly.

I have looked through pseudoscheme.  In derive.scm it appears you are
expanding forms down to the primitive expression types.  If this is
the case, hygenic macro expansion will not slow down your execution.

One way that hygenic expansion screws small implementations is the
large number of symbols it generates.  Each symbol in SCM occupies 3
cons cells (symbol header + link in hash bucket + value cell= 12 bytes)
plus a malloc()ed string.  This storage does not get GCed; It stays
allocated until SCM is exited.  I don't have a figure on this yet, but
I expect it will make a big difference on a 1Meg IBMPC, where Jacal in
SCM still fits.

The solution I would like to see would be one where the renaming and
macro expansion take place only when a macro is defined and in the
application of the macro.  That way, these costs would only be
incurred if macros were used.  I have discussed this some with William
Clinger <will@skinner.cs.uoregon.edu> but he tells me that it has been
previously investigated and doesn't work.