[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
How to let macros work without defining what a macro is...
Date: 27 Mar 1985 10:19 EST (Wed)
From: Bill Rozas <JINX%MIT-OZ@MIT-MC.ARPA>
This assumes that all macros work at the s-expression level,
which is not true in our implementation. The only way to provide both
(especially syntax-expand) in all cases would be to fully reduce to
s-code and then invert to s-expressions. This would imply full
(recursive) expansion always.
In our system macros translate from s-expressions to s-code.
There are a few utilities, however, to emulate s-expression level
macros built on top of this. But macros like COND, LET, etc are never
translated at the s-expression level.
No, you missed the point. You can implement these special forms however
you want. What I'm proposing is something that takes forms which may be
in an extended syntax and translates it into a standard syntax.
eg, suppose the only extended forms in some dialect are WHEN and UNLESS.
Regardless of how those are implemented (perhaps directly represented
in S-code, perhaps translated to something else in S-code, whatever),
all you have to provide is (literally) the following function:
(DEFINE (PRIMITIVE-SYNTAX-EXPAND FORM)
(COND ((ATOM FORM) FORM)
((EQ (CAR FORM) 'WHEN)
`(COND (,(CADR FORM) ,@(CDDR FORM))))
((EQ (CAR FORM) 'UNLESS)
`(COND ((NOT ,(CADR FORM)) ,@(CDDR FORM))))
(T FORM)))
You never have to call the function internally in the system. It simply
has to be available for users who want to use it. It must be the
responsibility of system maintainers to keep it up to date so that
code-manipulating tools can be written which assume a fixed number
of special forms and new special forms can later be added to standard
Scheme which do not cause a need to rewrite those tools.
Suppose that the only special forms we could agree on being standard
were LAMBDA, QUOTE, and SETQ. Suppose that someone insisted that
(IF X Y Z)
had to be written
(*IF (LAMBDA () X)
(LAMBDA () Y)
(LAMBDA () Z))
and *IF had to be a function, etc. Assume similar rewrites were suggested
for other special forms. Now consider a user program in a particular
dialect which had extra special forms (eg, DEFINE, COND, ...):
(DEFINE (USED-FREE-IN EXP VAR TAIL?)
(COND ((ATOM VAR) (EQ EXP VAR))
(FLAG
(COND ((NULL EXP) NIL)
((USED-FREE-IN (CAR EXP) VAR NIL) T)
(T
(USED-FREE-IN (CDR EXP) VAR T))))
((EQ (CAR EXP) 'LAMBDA)
(COND ((MEMQ VAR (CADR EXP)) NIL)
(T
(USED-FREE-IN (CDDR EXP) VAR T))))
((EQ (CAR EXP) 'SETQ)
(OR (EQ EXP (CADR FORM))
(USED-FREE-IN (CADDR EXP) VAR NIL)))
((EQ (CAR EXP) 'QUOTE) NIL)
(T
(USED-FREE-IN EXP VAR T))))
If I didn't blow it, this program "works" on input which contains
LAMBDA, SETQ, and QUOTE but does not work on input that contains
COND, etc. It could, however, work on those, too, by simply making it
say:
(DEFINE (USED-FREE-IN EXP VAR TAIL?)
(LET ((EXP (PRIMITIVE-SYNTAX-EXPAND EXP)))
(COND ((ATOM VAR) (EQ EXP VAR))
(FLAG
(COND ((NULL EXP) NIL)
((USED-FREE-IN (CAR EXP) VAR NIL) T)
(T
(USED-FREE-IN (CDR EXP) VAR T))))
((EQ (CAR EXP) 'LAMBDA)
(COND ((MEMQ VAR (CADR EXP)) NIL)
(T
(USED-FREE-IN (CDDR EXP) VAR T))))
((EQ (CAR EXP) 'SETQ)
(OR (EQ EXP (CADR FORM))
(USED-FREE-IN (CADDR EXP) VAR NIL)))
((EQ (CAR EXP) 'QUOTE) NIL)
(T
(USED-FREE-IN EXP VAR T)))))
The user could write PRIMITIVE-SYNTAX-EXPAND himself, but he'd have
to:
(a) Make sure his understanding of the syntax equivalences was
letter perfect (the system implementors have a better chance
of getting this right)
(b) Update the function every time the dialect changed. ie, adding
a special form if PRIMITIVE-SYNTAX-EXPAND is not a system primitive
function is an incompatible change, but is a compatible change
if PRIMITIVE-SYNTAX-EXPAND is kept in synch with available special
forms.
It would be possible to have forms which were not translatable. They
should simply be advertised as such and PRIMITIVE-SYNTAX-EXPAND should err
when it sees them so that the user doesn't think he's winning when he's
not.
Does this make it clearer?
-kmp