[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.lisp

MAKUNBOUND: should remove symbol macros?

Kaz Kylheku

5/15/2015 7:31:00 PM

ANSI CL says, of FMAKUNBOUND:

"Removes the function or macro definition, if any, of name in the global
environment."

But for MAKUNBOUND:

"Makes the symbol be unbound, regardless of whether it was previously bound."

Well, does that mean variables, or symbol macros too? Moreover, what about the
special variable status of the symbol?

Are global symbol macros "bindings"? Under DEFINE-SYMBOL-MACRO, there is
a blurb of text which suggests they are:

A binding for a symbol macro can be shadowed by let or symbol-macrolet.

If there is such a thing a "binding for a symbol macro", then MAKUNBOUND
had better delete it.

CLISP: making it unbound doesn't affect special status:

[1]> (defvar x)
X
[2]> (special-variable-p 'x) ;; CLISP extension in package EXT
T
[3]> (makunbound 'x)
X
[4]> (special-variable-p 'x)
T
[5]> (boundp 'x)
NIL

Is that conforming? It seems logically inconsistent because (boundp 'x) -> nil
is telling us that X is not a variable! Yet special-variable-p insists
that X is a variable. I say that if it's unbound, it has no such status.

CLISP: symbol macros are not bindings, and MAKUNBOUND doesn't wipe them:

[1]> (define-symbol-macro x '(i am x))
X
[2]> x
(I AM X)
[3]> (boundp 'x)
NIL
[4]> (makunbound 'x)
X
[5]> x
(I AM X)
[6]>

CLISP: constants are bindings, but cannot be unbound by MAKUNBOUND:

[1]> (defconstant x 42)
X
[2]> (boundp 'x)
T
[3]> (makunbound 'x)

*** - MAKUNBOUND: X is a constant, may not be used as a variable
The following restarts are available:

What? I didn't *use* anything; I merely requested its nonexistence!!!
8 Answers

Barry Margolin

5/15/2015 7:55:00 PM

0

In article <20150515121906.638@kylheku.com>,
Kaz Kylheku <kaz@kylheku.com> wrote:

> ANSI CL says, of FMAKUNBOUND:
>
> "Removes the function or macro definition, if any, of name in the global
> environment."
>
> But for MAKUNBOUND:
>
> "Makes the symbol be unbound, regardless of whether it was previously
> bound."
>
> Well, does that mean variables, or symbol macros too? Moreover, what about
> the
> special variable status of the symbol?
>
> Are global symbol macros "bindings"? Under DEFINE-SYMBOL-MACRO, there is
> a blurb of text which suggests they are:
>
> A binding for a symbol macro can be shadowed by let or symbol-macrolet.
>
> If there is such a thing a "binding for a symbol macro", then MAKUNBOUND
> had better delete it.
>
> CLISP: making it unbound doesn't affect special status:
>
> [1]> (defvar x)
> X
> [2]> (special-variable-p 'x) ;; CLISP extension in package EXT
> T
> [3]> (makunbound 'x)
> X
> [4]> (special-variable-p 'x)
> T
> [5]> (boundp 'x)
> NIL
>
> Is that conforming? It seems logically inconsistent because (boundp 'x) ->
> nil
> is telling us that X is not a variable! Yet special-variable-p insists
> that X is a variable. I say that if it's unbound, it has no such status.

Of course it does. Specialness is associated with the symbol, not the
binding. The variable was unbound when you declared it with DEFVAR,
since you didn't provide an initial value, and MAKUNBOUND doesn't change
that.

>
> CLISP: symbol macros are not bindings, and MAKUNBOUND doesn't wipe them:
>
> [1]> (define-symbol-macro x '(i am x))
> X
> [2]> x
> (I AM X)
> [3]> (boundp 'x)
> NIL
> [4]> (makunbound 'x)
> X
> [5]> x
> (I AM X)
> [6]>

One thing to note: the symbol macro has no effect on (symbol-value 'x).
It's only effective when it's used as a variable in an expression, not
when operating on the symbol as first-class data.

There probably SHOULD be a way to undo DEFINE-SYMBOL-MACRO, I think it's
just an omission in the spec.

>
> CLISP: constants are bindings, but cannot be unbound by MAKUNBOUND:
>
> [1]> (defconstant x 42)
> X
> [2]> (boundp 'x)
> T
> [3]> (makunbound 'x)
>
> *** - MAKUNBOUND: X is a constant, may not be used as a variable
> The following restarts are available:
>
> What? I didn't *use* anything; I merely requested its nonexistence!!!

No, you told it to set its value slot to the special "unbound" value.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Kaz Kylheku

5/15/2015 11:09:00 PM

0

On 2015-05-15, Barry Margolin <barmar@alum.mit.edu> wrote:
> In article <20150515121906.638@kylheku.com>,
> Kaz Kylheku <kaz@kylheku.com> wrote:
>
>> ANSI CL says, of FMAKUNBOUND:
>>
>> "Removes the function or macro definition, if any, of name in the global
>> environment."
>>
>> But for MAKUNBOUND:
>>
>> "Makes the symbol be unbound, regardless of whether it was previously
>> bound."
>>
>> Well, does that mean variables, or symbol macros too? Moreover, what about
>> the
>> special variable status of the symbol?
>>
>> Are global symbol macros "bindings"? Under DEFINE-SYMBOL-MACRO, there is
>> a blurb of text which suggests they are:
>>
>> A binding for a symbol macro can be shadowed by let or symbol-macrolet.
>>
>> If there is such a thing a "binding for a symbol macro", then MAKUNBOUND
>> had better delete it.
>>
>> CLISP: making it unbound doesn't affect special status:
>>
>> [1]> (defvar x)
>> X
>> [2]> (special-variable-p 'x) ;; CLISP extension in package EXT
>> T
>> [3]> (makunbound 'x)
>> X
>> [4]> (special-variable-p 'x)
>> T
>> [5]> (boundp 'x)
>> NIL
>>
>> Is that conforming? It seems logically inconsistent because (boundp 'x) ->
>> nil
>> is telling us that X is not a variable! Yet special-variable-p insists
>> that X is a variable. I say that if it's unbound, it has no such status.
>
> Of course it does. Specialness is associated with the symbol, not the
> binding. The variable was unbound when you declared it with DEFVAR,
> since you didn't provide an initial value, and MAKUNBOUND doesn't change
> that.
>
>>
>> CLISP: symbol macros are not bindings, and MAKUNBOUND doesn't wipe them:
>>
>> [1]> (define-symbol-macro x '(i am x))
>> X
>> [2]> x
>> (I AM X)
>> [3]> (boundp 'x)
>> NIL
>> [4]> (makunbound 'x)
>> X
>> [5]> x
>> (I AM X)
>> [6]>
>
> One thing to note: the symbol macro has no effect on (symbol-value 'x).
> It's only effective when it's used as a variable in an expression, not
> when operating on the symbol as first-class data.
>
> There probably SHOULD be a way to undo DEFINE-SYMBOL-MACRO, I think it's
> just an omission in the spec.
>
>>
>> CLISP: constants are bindings, but cannot be unbound by MAKUNBOUND:
>>
>> [1]> (defconstant x 42)
>> X
>> [2]> (boundp 'x)
>> T
>> [3]> (makunbound 'x)
>>
>> *** - MAKUNBOUND: X is a constant, may not be used as a variable
>> The following restarts are available:
>>
>> What? I didn't *use* anything; I merely requested its nonexistence!!!
>
> No, you told it to set its value slot to the special "unbound" value.

I'm tripped up by the stupid terminology again that a binding is
an association between a symbol and a value (rather than an abstract
storage location).

Thus DEVAR "establishes a dynamic variable", but doesn't give it a binding
(and it may have one already).

MAKUNBOUND doesn't "disestablish" a dynamic variable; it just robs
it of a value.

We can store value into a dynamic variable which doesn't have a binding.
The binding is then created (to that value).

Okay, now here is a problem.

The description of the SETQ form says this:

"Assigns values to variables."

"(setq var1 form1 var2 form2 ...) is the simple variable assignment
statement of Lisp."

What does it mean to assign? It's not explained under SETQ; but there is a
Glossary entry for the term:

assign v.t. (a variable) to change the value of the variable in a binding
that has already been established. See the special operator setq.

Oops, problem!

;; establish never-been-seen-before as a dynamic variable,
;; without establishing a binding:

(defvar never-been-seen-before)

;; Assignment means to change the value in
;; a binding that has been established,
;; so the following isn't correct: there is no binding.

(setq never-been-seen-before 42)

It seems that part of the ANSI CL document is written from the point of
view of "binding refers to an abstract storage location that is entered into
some environment under a symbol", even though other parts insist that
a binding is an association to a value.

What is a dynamic variable?

dynamic variable n. a variable the binding for which is in the dynamic
environment. See special.

So if something has no binding, it cannot be a dynamic variable, oops!
Yet MAKUNBOUND supposedly preserves a variable as such, yet only
takes away its binding.

Barry Margolin

5/15/2015 11:37:00 PM

0

In article <20150515153726.260@kylheku.com>,
Kaz Kylheku <kaz@kylheku.com> wrote:

> I'm tripped up by the stupid terminology again that a binding is
> an association between a symbol and a value (rather than an abstract
> storage location).

This is an unfortunate legacy of CL's MACLISP roots. MACLISP didn't have
much of a distinction between symbols and variables, and didn't try to
describe it in terms of abstract bindings or environments. There were
just symbols, and they had value cells. SETQ would store something into
the value cell. MAKUNBOUND would remove the contents of the value cell
(internally, I think it actually stored a special value that was
recognized as "unbound").

The thing to notice about MAKUNBOUND is that its argument is a symbol.
It's not a special operator or macro, so it can't operate on a variable
in the environment. So it's just dealing with symbols as data, and
operating on the symbol's value cell, like SYMBOL-VALUE. It's probably
implemented something like:

(defun makunbound (symbol)
(setf (symbol-value symbol) INTERNAL::*UNBOUND-MARKER*))

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

William James

5/17/2015 4:24:00 AM

0

Barry Margolin wrote:

> In article <20150515121906.638@kylheku.com>,
> Kaz Kylheku <kaz@kylheku.com> wrote:
>
> > ANSI CL says, of FMAKUNBOUND:
> >
> > "Removes the function or macro definition, if any, of name in the global
> > environment."
> >
> > But for MAKUNBOUND:
> >
> > "Makes the symbol be unbound, regardless of whether it was previously
> > bound."
> >
> > Well, does that mean variables, or symbol macros too? Moreover, what about
> > the
> > special variable status of the symbol?
> >
> > Are global symbol macros "bindings"? Under DEFINE-SYMBOL-MACRO, there is
> > a blurb of text which suggests they are:
> >
> > A binding for a symbol macro can be shadowed by let or symbol-macrolet.
> >
> > If there is such a thing a "binding for a symbol macro", then MAKUNBOUND
> > had better delete it.
> >
> > CLISP: making it unbound doesn't affect special status:
> >
> > [1]> (defvar x)
> > X
> > [2]> (special-variable-p 'x) ;; CLISP extension in package EXT
> > T
> > [3]> (makunbound 'x)
> > X
> > [4]> (special-variable-p 'x)
> > T
> > [5]> (boundp 'x)
> > NIL
> >
> > Is that conforming? It seems logically inconsistent because (boundp 'x) ->
> > nil
> > is telling us that X is not a variable! Yet special-variable-p insists
> > that X is a variable. I say that if it's unbound, it has no such status.
>
> Of course it does. Specialness is associated with the symbol, not the
> binding. The variable was unbound when you declared it with DEFVAR,
> since you didn't provide an initial value, and MAKUNBOUND doesn't change
> that.
>
> >
> > CLISP: symbol macros are not bindings, and MAKUNBOUND doesn't wipe them:
> >
> > [1]> (define-symbol-macro x '(i am x))
> > X
> > [2]> x
> > (I AM X)
> > [3]> (boundp 'x)
> > NIL
> > [4]> (makunbound 'x)
> > X
> > [5]> x
> > (I AM X)
> > [6]>
>
> One thing to note: the symbol macro has no effect on (symbol-value 'x).
> It's only effective when it's used as a variable in an expression, not
> when operating on the symbol as first-class data.
>
> There probably SHOULD be a way to undo DEFINE-SYMBOL-MACRO, I think it's
> just an omission in the spec.
>
> >
> > CLISP: constants are bindings, but cannot be unbound by MAKUNBOUND:
> >
> > [1]> (defconstant x 42)
> > X
> > [2]> (boundp 'x)
> > T
> > [3]> (makunbound 'x)
> >
> > *** - MAKUNBOUND: X is a constant, may not be used as a variable
> > The following restarts are available:
> >
> > What? I didn't use anything; I merely requested its nonexistence!!!
>
> No, you told it to set its value slot to the special "unbound" value.

Paul Graham, May 2001:

A hacker's language is terse and hackable. Common Lisp is not.

The good news is, it's not Lisp that sucks, but Common Lisp.

Pascal J. Bourguignon

5/18/2015 6:27:00 AM

0

Barry Margolin <barmar@alum.mit.edu> writes:

> There probably SHOULD be a way to undo DEFINE-SYMBOL-MACRO, I think it's
> just an omission in the spec.

There's always (unintern symbol)
Good for both specialness and symbol-macros.


>> CLISP: constants are bindings, but cannot be unbound by MAKUNBOUND:
>>
>> [1]> (defconstant x 42)
>> X
>> [2]> (boundp 'x)
>> T
>> [3]> (makunbound 'x)
>>
>> *** - MAKUNBOUND: X is a constant, may not be used as a variable
>> The following restarts are available:
>>
>> What? I didn't *use* anything; I merely requested its nonexistence!!!
>
> No, you told it to set its value slot to the special "unbound" value.

Indeed, constant variables have constant bindings, therefore you cannot
change the binding, be it to a different value or no value (unbound).

--
__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

Pascal J. Bourguignon

5/18/2015 6:37:00 AM

0

Kaz Kylheku <kaz@kylheku.com> writes:

> Thus DEFVAR "establishes a dynamic variable", but doesn't give it a binding
> (and it may have one already).

Wrong. The ANSI Common Lisp specification is often the most concise
form to describe Common Lisp operators. If you try something shorter,
you make it wrong.

defvar establish name as a dynamic variable.

defvar, assigns initial-value (if supplied) to the dynamic variable
named name only if name is not already bound.

If no initial-value is supplied, defvar leaves the value cell of the
dynamic variable named name undisturbed; if name was previously
bound, its old value persists, and if it was previously unbound, it
remains unbound.

If documentation is supplied, it is attached to name as a
documentation string of kind variable.

defvar normally appear as a top level form, but it is meaningful for
them to appear as non-top-level forms. However, the compile-time
side effects described below only take place when they appear as top
level forms.

If a defvar form appears as a top level form, the compiler must
recognize that the name has been proclaimed special. However, it
must neither evaluate the initial-value form nor assign the dynamic
variable named name at compile time.

There may be additional (implementation-defined) compile-time or
run-time side effects, as long as such effects do not interfere with
the correct operation of conforming programs.


> MAKUNBOUND doesn't "disestablish" a dynamic variable; it just robs
> it of a value.
>
> We can store value into a dynamic variable which doesn't have a binding.
> The binding is then created (to that value).
>
> Okay, now here is a problem.
>
> The description of the SETQ form says this:
>
> "Assigns values to variables."
>
> "(setq var1 form1 var2 form2 ...) is the simple variable assignment
> statement of Lisp."
>
> What does it mean to assign? It's not explained under SETQ; but there is a
> Glossary entry for the term:
>
> assign v.t. (a variable) to change the value of the variable in a binding
> that has already been established. See the special operator setq.
>
> Oops, problem!
>
> ;; establish never-been-seen-before as a dynamic variable,
> ;; without establishing a binding:
>
> (defvar never-been-seen-before)
>
> ;; Assignment means to change the value in
> ;; a binding that has been established,
> ;; so the following isn't correct: there is no binding.
>
> (setq never-been-seen-before 42)
>
> It seems that part of the ANSI CL document is written from the point of
> view of "binding refers to an abstract storage location that is entered into
> some environment under a symbol", even though other parts insist that
> a binding is an association to a value.
>
> What is a dynamic variable?
>
> dynamic variable n. a variable the binding for which is in the dynamic
> environment. See special.
>
> So if something has no binding, it cannot be a dynamic variable, oops!
> Yet MAKUNBOUND supposedly preserves a variable as such, yet only
> takes away its binding.

No, again, you are confusing special symbol with dynamic variable.

It is the symbol which is declared special.
It is the variable that has dynamic bindings.
makunbound removes the binding, so the variable doesn't exist anymore:

(declaim (special zozo))

(defun f ()
zozo)

(f)
Debug: Unbound variable: zozo

; No variable named zozo exists so far.


(let ((zozo 42)) (f))
--> 42

; LET created a dynamic variable named zozo, for the duration of its
; evaluation.

--
__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

Kaz Kylheku

5/19/2015 9:20:00 PM

0

On 2015-05-18, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
>
>> Thus DEFVAR "establishes a dynamic variable", but doesn't give it a binding
>> (and it may have one already).
>
> Wrong. The ANSI Common Lisp specification is often the most concise
> form to describe Common Lisp operators. If you try something shorter,
> you make it wrong.

If an excerpt from a text is not merely incomplete but somehow incorrect, the
text has a flaw. Robust texts have the property that we can cite
from them.

> defvar, assigns initial-value (if supplied) to the dynamic variable
> named name only if name is not already bound.

Conceptually conficts with the definition of assignment from the Glossary,
which specifically requires a binding!

>> What is a dynamic variable?
>>
>> dynamic variable n. a variable the binding for which is in the dynamic
>> environment. See special.
>>
>> So if something has no binding, it cannot be a dynamic variable, oops!
>> Yet MAKUNBOUND supposedly preserves a variable as such, yet only
>> takes away its binding.
>
> No, again, you are confusing special symbol with dynamic variable.

"See special" is quoted text; I haven't remarked upon it at all.

> It is the symbol which is declared special.
> It is the variable that has dynamic bindings.
> makunbound removes the binding, so the variable doesn't exist anymore:

I don't think that is the intent behind the muddled language that underlies the
description of dynamic variable binding in ANSI CL. Unbound does not mean
"variable doesn't exist".

My point is that there is muddled language in there which could really
use some attention.

I also suspect that some of the current terminology would not survive
a proper editing job, which would affect the way we talk about
the language.

> (declaim (special zozo))
>
> (defun f ()
> zozo)
>
> (f)
> Debug: Unbound variable: zozo
>
> ; No variable named zozo exists so far.
>
>
> (let ((zozo 42)) (f))
> --> 42
>
> ; LET created a dynamic variable named zozo, for the duration of its
> ; evaluation.

Note that we can take your entire example and change "(declaim (special
zozo))" for "(defvar zozo)". (f) will run into the unbound variable situation,
or proceed, in the same ways.

Can you then still claim *with a straight face* that "no variable named zozo
exists"? Even though there is something called DEFVAR right above?

Pascal J. Bourguignon

5/19/2015 9:22:00 PM

0

Kaz Kylheku <kaz@kylheku.com> writes:

> On 2015-05-18, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> Kaz Kylheku <kaz@kylheku.com> writes:
>>
>>> Thus DEFVAR "establishes a dynamic variable", but doesn't give it a binding
>>> (and it may have one already).
>>
>> Wrong. The ANSI Common Lisp specification is often the most concise
>> form to describe Common Lisp operators. If you try something shorter,
>> you make it wrong.
>
> If an excerpt from a text is not merely incomplete but somehow incorrect, the
> text has a flaw. Robust texts have the property that we can cite
> from them.

That's not how mathematics work, and formal specifications for formal
languages are mathematics.


>> defvar, assigns initial-value (if supplied) to the dynamic variable
>> named name only if name is not already bound.
>
> Conceptually conficts with the definition of assignment from the Glossary,
> which specifically requires a binding!

Unfortunately, the ANSI Common Lisp standard is not a formal
specification. You have to use your brains.

>> It is the symbol which is declared special.
>> It is the variable that has dynamic bindings.
>> makunbound removes the binding, so the variable doesn't exist anymore:
>
> I don't think that is the intent behind the muddled language that underlies the
> description of dynamic variable binding in ANSI CL. Unbound does not mean
> "variable doesn't exist".

True. But it is often the error you will get when trying to use an
undefined variable.

$ clall -r 'x'

Armed Bear Common Lisp The variable X is unbound.
Clozure Common Lisp Unbound variable: X
CLISP EVAL: variable X has no value
CMU Common Lisp Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable X is unbound.
ECL The variable X is unbound.
SBCL The variable X is unbound.


> My point is that there is muddled language in there which could really
> use some attention.
>
> I also suspect that some of the current terminology would not survive
> a proper editing job, which would affect the way we talk about
> the language.

Possibly. A formal definition would probably help simplify and
generalize.


>> (declaim (special zozo))
>>
>> (defun f ()
>> zozo)
>>
>> (f)
>> Debug: Unbound variable: zozo
>>
>> ; No variable named zozo exists so far.
>>
>>
>> (let ((zozo 42)) (f))
>> --> 42
>>
>> ; LET created a dynamic variable named zozo, for the duration of its
>> ; evaluation.
>
> Note that we can take your entire example and change "(declaim (special
> zozo))" for "(defvar zozo)". (f) will run into the unbound variable situation,
> or proceed, in the same ways.
>
> Can you then still claim *with a straight face* that "no variable named zozo
> exists"? Even though there is something called DEFVAR right above?

That was kind of my point, that defvar without an initial value, and
without a pre-existing binding, doesn't really define a variable, since
the glossary defines a variable as
"n. a binding in the ``variable'' namespace.".

--
__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