TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


Forums >


Re: makunbound under dynamic binding

Pascal J. Bourguignon

6/11/2016 11:41:00 AM

Kaz Kylheku <545-066-4921@kylheku.com> writes:

> There are still differences that will remain:
> * If makunbound does operate on the top-level binding of a variable,
> then in that case, the special status of the symbol, if any, is also
> removed. Afterward, newly processed forms which bind the symbol will
> exhibit lexical binding, unless the symbol is re-introduced as a
> dynamically scoped variable.

The thing is that you can declare a symbol special without making it
bound, either with (defvar *foo*) or (declaim (special *foo*)).
This shows that being special and being bound are two orthogonal things.
Of course, it's unfortunate that there's no way to undeclare the
specialness of a symbol.

However notice that local special declaration only apply to the local
scope (not to embedded scopes), as it's clearly indicated and
exemplified in the clhs (I don't remember if in the LET or SPECIAL

(defun f ()
(declare (special foo))

(let ((foo 42))
(declare (special foo))
;; this foo=42 is dynaminc binding
(list (f)
(let ((foo 33))
;; this foo=33 is lexical binding!
(list foo
(declare (special foo))
--> (42 (33 42 42))

Otherwise you may want to draw a full diagram of all the states,
( bound / unbound | special / not-special | global / local ),
and labels the arrows with the operators providing the
transition. You'll see that in CL, only a few state are available
(eg. not-special global doesn't exist for variables (only symbol
macros), not-special local is never unbound, etc), and on the remaining
possible transitions, only a few of them are possible thru CL operators.

To understand why you have to consider the two different use cases:
compiling a static program, and evaluating forms at the REPL.

Clearly, defvar or declaim special are designed for static program
compilation. makunbound is more of a REPL thing.

In "modern" Common Lisp programs, you would just a more explicit
mechanism instead of makunbound for whatever you would have used it in
older programs. I'm not saying that it's necessarily a good thing, I
don't really like this influence from development processes from alien
and lesser languages. So you could want to make that diagram fuller,
providing operators to navigate all the states, even if they wouldn't be
useful a-priori for static programs batch-compiled (thanks asdf and
quicklisp): they would be useful at the REPL, and with different kinds
of development processes.

>> I would note that MAKUNBOUND is specified to work on a SYMBOL, not on
>> some binding. Therefore I'd rather ensure that all the current bindings
>> in the current thread whether shadowed or not, be unbound by makunbound.
> It is written that makunbound makes the symbol be unbound. But under
> "Side Effects" it is clarified that it modifies the value cell of the
> symbol, which is a fairly well-defined concept in CL.
> A symbol, conceptually, has but one value-cell (if we don't
> consider threads for a moment).
> Under this "one value cell" model, re-binding a variable saves the
> prior value of the value cell somewhere, and installs a new one,
> as if by assignment. When that binding form terminates it restores
> the prior value. By restoring the prior value, it restores the binding,
> since a binding and value are the same thing in CL.
> The saved values aren't bindings; if makunbound clobbered them, it
> could arguably be over-stepping its requirements.

Both semantics could be valid. It's too bad we don't have a formal
semantic specification for CL (yet?).

__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk