[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
GLS's clarifications list (moderately long)
- To: apollo!dfm@UW-BEAVER.ARPA, COMMON-LISP@SU-AI.ARPA
- Subject: GLS's clarifications list (moderately long)
- From: Guy Steele <gls@THINK-AQUINAS.ARPA>
- Date: Fri, 20 Dec 85 11:28 EST
- Cc: gls@THINK-AQUINAS.ARPA
- In-reply-to: <8512200453.AA03243@uw-beaver.arpa>
Date: Thu, 19 Dec 85 17:18:36 EST
+ COMMON LISP's #n=/#n# syntax invites the creation of circular lists. For
example, the following seems more tasteful than the example with star, and
is, I believe, fairly perspicuous:
(mapcar #'cons p-list '#0=(property value . #0#))
Of course, the example with the STAR function:
(mapcar #'cons baz (star 'foo))
allows the value to be calculated at run time.
The obvious way to do it with #n= syntax is to use backquote:
(mapcar #'cons p-list `#0=(,property ,value . #0#))
but right now backquote is not defined to work on circular lists.
We could define it to do so (or maybe introduce `@ to handle the circular case).
Does COMMON LISP guarantee that we can successfully call inspect on a circular
list or structure? It should.
I agree, but it isn't addressed explicitly.
A related clarification. Not only can data be circular, so can code.
It should probably "be an error" to try to eval something like
(progn . #0=((f) . #0#)) ; an ugly way of saying (loop (f))
A LISP for the IBM 370 developed at Yorktown by Fred Blair and
colleagues actually made this work in both interpreter and compiler.
Fred was very proud of it.
+ Regarding globals: ... I'd rather not see globals
introduced into the language, but deep binding implementations may really need
Actually, a trick that was designed for S-1 LISP may reduce the overhead
in deep-binding implementations: let there be a counter associated with
the global value cell, initially zero. Every time a deep binding of
that variable is created, the counter is incremented, and when the
binding is destroyed, the counter is decremented. Lookup of a special
variable proceeds as follows: first check the global counter. If it is
zero, just grab the global value cell. Otherwise do the usual
deep-binding search. Process-switching involves nothing new. Note that
if there are several processes, they share a single counter. The
counter merely serves as a hint: you might do the search even if you
didn't really have to (in the case where your process hasn't done a
special binding but some other process did), but in the truly global
case, no one has bound it and so the search is eliminated. It does
increase the cost of the lookup in the special case, but only by a
single zero check. One does have to be careful to destroy all bindings
(in order to adjust the counts) when a process is destroyed if the
efficiency is to be maintained.
+ (-: The obvious way to have an all-purpose undo function is to generalize setf
to work with an odd number of arguments:
(setf (symbol-function 'foo)) => (undefun 'foo)
(setf (symbol-value '*foov*)) => (mkunbound '*foov*) :-)
I would favor this quite a bit had not SETF been generalized to any even
number of argument forms rather than just two. With the generalization,
the chances for accidental lossage are too great. Maybe we could make one
argument form do an undo, but three or five would be illegal.
- Don Morrison