[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: COMPILER-LET
Here's an example were COMPILER-LET helps and replacing it with a
MACRO-LET seems rather unnatural. It is simplified from the
implementation of CLOCKS, a shell that supports multiple distributd
agents, each with its own blackboard. There is a general language form,
that for the current discussion, we will say looks like
(VAL THING PNAME)
where THING is either a hypothesis on an agent's blackboard or a
representation of an agent -- some specialized knowledge sources can be
scoped into multiple agents. The VAL form can be either an odd or even
numbered arg to SETF and either refers to the PNAME property of a
hypothesis or that property on the header of THING's blackboard. The
access in each case is quite different. The VAL macro has an
implementation that resembles
(DEFMACRO VAL (THING PNAME)
(IF (MEMBER THING *SCOPED-AGENTS*)
(EXPAND-FOR-AGENT THING PNAME)
(EXPAND-FOR-HYPOTHESIS THING PNAME)))
Further, there is a language form that enables specialized knowledge
sources' accesses to multiple agents:
(DEFMACRO WITH-SCOPED-AGENT (AGENT &BODY BODY)
`(COMPILER-LET((*SCOPED-AGENTS* (CONS ',AGENT *SCOPED-AGENTS*)))
,@BODY))
Of course there is a top-level definition like
(DEFVAR *SCOPED-AGENTS* NIL)
There doesn't seem to be anything unclear or arcane about the above.
Further, if the expansion of VAL depends upon other things that are
context dependent (it does), it is hard to think of a cleaner
implementation tool that is independent of the implementation of the
underlying LISP compiler.
As to the question of making EVAL and the compiler compatible, I must
admit that I haven't written a CL system so I may be wrong in saying
that it is easy but two approaches immediately suggest themselves: The
first is that EVAL should just compile its argument, execute it and mark
it for the GC. This is what I always did in the LISPs that I
implemeneted and the gain in compatibility was a joy. The second
approach is for those who find the first suggestion fatuous.
In point of fact, an EVAL function for CL must keep around an
environment object -- else how can it know which variables are lexical
and know which operators are really lexical macros? Why not just put
the COMPILER-LETed special variables in the environemnt object--marked
as such--then PROGV or PROGW them exactly around EVAL's macro expansion
activity. How could this possibly be a large change to current
implementations?