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

SPECIAL FUNCTION NAME [Gall: Bug Report]



    Date: Tue, 2 Apr 85 15:01 EST
    From: Nick Gall <Gall at MIT-MULTICS.ARPA>

    ...As for its usefulness, I am writing a command processor, and I
    wish to prevent the user from typing in forms that might abort
    the processor (e.g., (exit), (reset-stack-group), etc.).  FLET
    would allow me to establish temporary global function definitions
    for these dangerous functions.  The code would be much clearer
    than saving the old function definitions, doing defuns (or setfs
    of symbol-functions) and then restoring the old definitions.

I think that special function binding was explicitly and intentionally
omitted from CL.  Symmetry with variables would suggest that they are
desirable, but there were reasons for their omission (descriptive and
implementation simplicity come to mind).

You could do what you need to do by implementing yourself a sort of
generalized special binding which is symmetric with SETF instead of with
SETQ, using UNWIND-PROTECT:

  (SETF-TEMPORARILY place value-form
    ... body-forms ...)

could expand into something like

  (LET ((SAVED-VALUE place))
    (UNWIND-PROTECT (PROGN (SETF SAVED-VALUE place)
			   ... body-forms ...)
		    (SETF place SAVED-VALUE)))

(with appropriate DEFSETF-like hair).  Now you have a much more
symmetrical facility, which will work not only with function bindings
(take place = (SYMBOL-FUNCTION ...)) but any other kind of location -
including CAR's of lists, lexical variables (!), etc.  (Think about it.)

We've been using exactly this facility in T (Yale Scheme) for quite a
while (in fact, it replaces specbinding altogether) and it's pretty
nice.  Perhaps even a little too powerful.

You run into problems if you're running in a multitasking or
multiprocessing environment.  Presumably special variable bindings are
local to a process in any such system (whether deep- or shallow-bound).
If you're multitasking you could imagine an UNWIND-PROTECT primitive for
changing dynamic state going from one process to another, so that you
could specbind arbitrary places; but this totally breaks down in a
multiprocessor system, where deep binding would be necessary.  How do
you deep-bind the car of a pair, or the 13th bit of a bit-vector?  That
would argue in favor of permitting function specbinding by special
dispensation, although how you'd implement it efficiently I can't
imagine.

For this particular application, though, isn't the right thing just to
set up a separate package?...

Jonathan