Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

flet vars

392 views
Skip to first unread message

TheFlyingDutchman

unread,
Apr 14, 2011, 9:51:56 PM4/14/11
to
Is it possible to change the values of the variables in an flet?

(flet ( (function1 () (format t "hi from function1~%")))
(function1)
; change what function1 refers to
(function1))

Anticomuna

unread,
Apr 15, 2011, 3:12:49 AM4/15/11
to

Use defun from inside the flet.

Pascal J. Bourguignon

unread,
Apr 15, 2011, 3:42:45 AM4/15/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

Functions are not variables, otherwise they'd be called variables, not functions.


(Which by the way, makes me notice that in scheme, so called "more
functionnal" than Common Lisp, there are no functions, only variables
(some of which have values that are anonymous functions, just like some
Common Lisp variables may have)).


(flet ((function1 () (format t "hi from outer function1~%")))
(function1)
(flet ((function1 () (format t "hi from inner function1~%")))
(function1))
(function1))

prints:
hi from outer function1
hi from inner function1
hi from outer function1
--> NIL


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Alessio Stalla

unread,
Apr 15, 2011, 3:55:53 AM4/15/11
to

Won't work. Defun always changes the global binding.

Anticomuna

unread,
Apr 15, 2011, 5:31:34 AM4/15/11
to

Well, this is stupid. My implementation updates the lexical
environment, if there's a function that uses the same symbol.

Anticomuna

unread,
Apr 15, 2011, 5:33:41 AM4/15/11
to
On 15 abr, 04:42, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:

> Functions are not variables, otherwise they'd be called variables, not functions.

It is a variable that points to a function.

Tim Bradshaw

unread,
Apr 15, 2011, 6:58:40 AM4/15/11
to
On 2011-04-15 10:33:41 +0100, Anticomuna said:

> It is a variable that points to a function.

No, it's not, not in common lisp. It is in scheme or any other lisp-1.

Captain Obvious

unread,
Apr 15, 2011, 7:54:23 AM4/15/11
to
A> Well, this is stupid. My implementation updates the lexical
A> environment, if there's a function that uses the same symbol.

Well, this is stupid.

http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/mac_defun.html
Defines a new function named function-name in the global environment.

TheFlyingDutchman

unread,
Apr 16, 2011, 3:22:36 AM4/16/11
to
(defun global_func (x) (+ x 2))


global_func --> (lambda (x) (+ x 2))
------ ----------------
symbol function object
---- ----------------

(flet ( (local_func (x) (+ x 2))))

local_func --> (lambda (x) (+ x 2))
--------- --------------------
???????? function object
--------- --------------------


(let ( (local_var 2) ) )

local_var --> 2
------------ -----------
????????? integer object
------------ -----------

What are the terms used to refer to local_func and local_var?

Ankur

unread,
Apr 16, 2011, 6:47:15 AM4/16/11
to
* TheFlyingDutchman <zzbb...@aol.com>

> (flet ( (local_func (x) (+ x 2))))
> (let ( (local_var 2) ) )
>
> What are the terms used to refer to local_func and local_var?

They are symbols. You are creating lexical bindings (unless local_var
is declared special).

Read the CLHS (as a textbook, not just for reference).

--
Ankur

Teemu Likonen

unread,
Apr 16, 2011, 7:50:42 AM4/16/11
to
* 2011-04-16T10:47:15Z * <an...@lipidity.com> wrote:

> Read the CLHS (as a textbook, not just for reference).

And I suggest starting from here:

http://www.gigamonkeys.com/book/variables.html
http://www.lispworks.com/documentation/HyperSpec/Body/03_a.htm

TheFlyingDutchman

unread,
Apr 16, 2011, 11:56:38 AM4/16/11
to
On Apr 16, 3:47 am, Ankur <an...@lipidity.com> wrote:
> * TheFlyingDutchman <zzbba...@aol.com>

>
> > (flet ( (local_func (x) (+ x 2))))
> > (let ( (local_var 2) ) )
>
> > What are the terms used to refer to local_func and local_var?
>
> They are symbols. You are creating lexical bindings (unless local_var
> is declared special).

(defvar global-value 10)

I have created a symbol "global-value" that I believe has 5 slots. One
to point to the symbol name, another to point to a value, one to point
to a function, one to point to a property list and one to point to a
package name.

(let ( (local-value 10) ) )
(flet ( (local-function (x) (+ x 2)) ) )

If local-value and local-function are called "symbols", then they must
have 5 slots and I should be able to use (setf (symbol-function
'local...) ) on them. If they don't have 5 slots then why are they
called the same thing as something that has 5 slots?

Captain Obvious

unread,
Apr 16, 2011, 1:35:23 PM4/16/11
to
T> (defvar global-value 10)
T> I have created a symbol "global-value" that I believe has 5 slots.

It looks like you do not understand difference between symbols and
variables.
Symbols can be created in many ways, including INTERN and MAKE-SYMBOL.
Reader interns symbols as it reads code. So when you type and evaluate, say,
'foo you create symbol:

CL-USER> 'foo
FOO
CL-USER> (setf (symbol-value 'foo) 35)
35
CL-USER> (symbol-value 'foo)
35

DEFVAR creates a global _variable_, basically, it declares that symbol can
be used as a variable.

You can achieve same effect by declaring it special, e.g.

CL-USER> (declaim (special foo))
; No value

And now you can legally use it is a variable:

CL-USER> foo
35

Although in most implementations you can use it as a variable even without a
declaim, but then behaviour is not specified by standard.

T> (let ( (local-value 10) ) )
T> (flet ( (local-function (x) (+ x 2)) ) )

T> If local-value and local-function are called "symbols",

Symbols act as names for variables. So, yeah, names are called symbols.

But let and flet establishes _lexical bindings_.
You should actually read what people reply to you instead of declaiming
bullshit which comes to your mind.

T> then they must have 5 slots and I should be able to use (setf
T> (symbol-function 'local...) ) on them.

Yes, you can do that, but it has nothing to do with value of a lexical
variable (binding).

It is called lexical because it only makes sense within textual piece of
code where it is defined.
And compiler generally uses symbols only to distinguish different variables
within this piece of code.
After compilation it might simply discard this information, so binary code
won't have any indications about how variables were named.

For example, compiler might decide that CPU register EAX will hold value of
LOCAL-VALUE.
Of course you can write (setf (symbol-function 'local-value) 'foo) but it
definitely won't affect value of register EAX.


Pascal Costanza

unread,
Apr 16, 2011, 2:15:58 PM4/16/11
to

(let ((function1 (lambda () (format t "hi from function1~%"))))
(flet ((function1 () (funcall function1)))
(function1)
(setq function1 (lambda () (format t "changed function1~%")))
(function1)))

If this is needed a lot, you will probably want to avoid the flets, and
instead funcall the variable function1 all the time.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.

TheFlyingDutchman

unread,
Apr 16, 2011, 2:25:22 PM4/16/11
to
On Apr 16, 10:35 am, "Captain Obvious"

<udode...@users.sourceforge.net> wrote:
>  T> (defvar global-value 10)
>  T> I have created a symbol "global-value" that I believe has 5 slots.
>
> It looks like you do not understand difference between symbols and
> variables.

What is the one that has five slots for (package-name, symbol-name,
symbol-value, symbol-function, property-list)?


> Symbols can be created in many ways, including INTERN and MAKE-SYMBOL.
> Reader interns symbols as it reads code. So when you type and evaluate, say,
> 'foo you create symbol:
>
> CL-USER> 'foo
> FOO

Does foo have 5 slots? If not, what it the structure of foo? Where
does foo reside?


> CL-USER> (setf (symbol-value 'foo) 35)
> 35
> CL-USER> (symbol-value 'foo)
> 35
>
> DEFVAR creates a global _variable_, basically, it declares that symbol can
> be used as a variable.
>
> You can achieve same effect by declaring it special, e.g.
>
> CL-USER> (declaim (special foo))
> ; No value
>
> And now you can legally use it is a variable:
>
> CL-USER> foo
> 35
>
> Although in most implementations you can use it as a variable even without a
> declaim, but then behaviour is not specified by standard.

Are you saying that some implementations would not allow

(setq my-var 10)

as the first reference to my-var?


>
>  T> (let ( (local-value 10) ) )
>  T> (flet ( (local-function (x) (+ x 2)) ) )
>
>  T> If local-value and local-function are called "symbols",
>
> Symbols act as names for variables. So, yeah, names are called symbols.
>
> But let and flet establishes _lexical bindings_.
> You should actually read what people reply to you instead of declaiming
> bullshit which comes to your mind.

This is the only reply I got: "They are symbols. You are creating


lexical bindings (unless local_var
is declared special). "

I never said that flet and let didn't establish lexical bindings. I
also didn't imply it.

>
>  T>  then they must have 5 slots and I should be able to use (setf
>  T> (symbol-function 'local...) ) on them.
>
> Yes, you can do that, but it has nothing to do with value of a lexical
> variable (binding).

If I am using it local to that lexical variable - why not?

>
> It is called lexical because it only makes sense within textual piece of
> code where it is defined.

OK. So I call (setf (symbol-function 'my-lexical-var) 10) within
textual piece of code where it is defined. What is the reason that
doesn't work since according to Ankur - my-lexical-var - is a symbol.

> And compiler generally uses symbols only to distinguish different variables
> within this piece of code.
> After compilation it might simply discard this information, so binary code
> won't have any indications about how variables were named.
>
> For example, compiler might decide that CPU register EAX will hold value of
> LOCAL-VALUE.
> Of course you can write (setf (symbol-function 'local-value) 'foo) but it
> definitely won't affect value of register EAX.

If register EAX is holding a value, it isn't holding a symbol.

According to the CLHS
http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm#symbol

a symbol has five attributes. _IF_ local-value is a symbol. What is
stored in register EAX is a value referred to by one of the five
attributes of a symbol.

Teemu Likonen

unread,
Apr 16, 2011, 2:44:05 PM4/16/11
to
* 2011-04-16T20:15:58+02:00 * Pascal Costanza wrote:

> (let ((function1 (lambda () (format t "hi from function1~%"))))
> (flet ((function1 () (funcall function1)))
> (function1)
> (setq function1 (lambda () (format t "changed function1~%")))
> (function1)))
>
> If this is needed a lot, you will probably want to avoid the flets,
> and instead funcall the variable function1 all the time.


Or something like this:


(defmacro let-flet (definitions &body body)
`(let ,(loop for def in definitions
collect `(,(first def) (lambda ,(second def)
,@(nthcdr 2 def))))
(flet ,(loop for def in definitions
collect `(,(first def) (&rest all)
(apply ,(first def) all)))
,@body)))


(let-flet ((fn () (print "original")))
(fn)
(setf fn (lambda (arg) (print arg)))
(fn "new"))

"original"
"new"

Pascal Costanza

unread,
Apr 16, 2011, 2:51:39 PM4/16/11
to
On 16/04/2011 20:44, Teemu Likonen wrote:
> * 2011-04-16T20:15:58+02:00 * Pascal Costanza wrote:
>
>> (let ((function1 (lambda () (format t "hi from function1~%"))))
>> (flet ((function1 () (funcall function1)))
>> (function1)
>> (setq function1 (lambda () (format t "changed function1~%")))
>> (function1)))
>>
>> If this is needed a lot, you will probably want to avoid the flets,
>> and instead funcall the variable function1 all the time.
>
>
> Or something like this:
>
>
> (defmacro let-flet (definitions&body body)

> `(let ,(loop for def in definitions
> collect `(,(first def) (lambda ,(second def)
> ,@(nthcdr 2 def))))
> (flet ,(loop for def in definitions
> collect `(,(first def) (&rest all)
> (apply ,(first def) all)))
> ,@body)))
>
>
> (let-flet ((fn () (print "original")))
> (fn)
> (setf fn (lambda (arg) (print arg)))
> (fn "new"))
>
> "original"
> "new"

Also, don't forget this:

(flet ((function1 () (print "foo")))
(function1)
(flet ((function1 () (print "bar")))
(function1)))

I guess we need more context what the OP actually wanted to achieve.

TheFlyingDutchman

unread,
Apr 16, 2011, 4:36:51 PM4/16/11
to
> I guess we need more context what the OP actually wanted to achieve.

My question came out of thinking about code William Clifford posted
that he wanted to refactor. He has four parameters to a function that
are function objects and all with default values.

I was thinking that instead of setting them in the call to the
function (e.g.):

(defun say-french () (format t "bonjour!~%"))
(defun my-func (&key (do-it (lambda () (format t "hi!~%"))))
(funcall do-it))
(my-func)
(my-func :do-it #'say-french)

He could set the function in a separate operation by wrapping things
in a let:

(let ((do-it (lambda () (format t "hi!~%"))))
(defun set-do-it (new-func) (setq do-it new-func))
(defun my-func () (funcall do-it))
)

(my-func)
(set-do-it #'say-french)
(my-func)

The question about flet was because he talked about getting rid of
the funcall's:

(flet ((do-it () (format t "hi!~%")))
; (defun set-do-it...
;*******
(defun my-func () (do-it))
;*******
)
(my-func)
; (set-do-it ...
(my-func)


But using your suggestion, the funcall's can be pushed to a lower
level:

(let ( (do-it-var (lambda () (format t "hi!~%"))))
(flet ((do-it () (funcall do-it-var)))
;*******
(defun my-func () (do-it))
;********
(defun set-do-it (new-func) (setq do-it-var new-func))
))

Captain Obvious

unread,
Apr 17, 2011, 11:28:42 AM4/17/11
to
??>> It looks like you do not understand difference between symbols and
??>> variables.

T> What is the one that has five slots for (package-name, symbol-name,
T> symbol-value, symbol-function, property-list)?

Symbol, obviously.
symbol-value can be used to get and set symbol's value.
But symbol's value becomes tied to variable with corresponding name only
when variable is declared special.

??>> Symbols can be created in many ways, including INTERN and MAKE-SYMBOL.
??>> Reader interns symbols as it reads code. So when you type and
??>> evaluate, say, 'foo you create symbol:
??>>
??>> CL-USER> 'foo
??>> FOO

T> Does foo have 5 slots? If not, what it the structure of foo? Where
T> does foo reside?

FOO is symbol, it has those "slots".

??>> Although in most implementations you can use it as a variable even
??>> without a declaim, but then behaviour is not specified by standard.

T> Are you saying that some implementations would not allow

T> (setq my-var 10)

T> as the first reference to my-var?

They might, in theory. SBCL generates warning.
Note that variable you get in this case might be not special, it might be
something like a "global lexical" -- it has value in global context, but it
can be shadowed lexically.
This behaviour is not specified by standard, thus it is better to avoid
this.

??>> But let and flet establishes _lexical bindings_.
??>> You should actually read what people reply to you instead of
??>> declaiming bullshit which comes to your mind.

T> This is the only reply I got: "They are symbols. You are creating
T> lexical bindings (unless local_var
T> is declared special). "

T> I never said that flet and let didn't establish lexical bindings. I
T> also didn't imply it.

"Lexical binding" is term you're looking for. I'm sure there you can find a
lot of materials if you search for this term.

??>> Yes, you can do that, but it has nothing to do with value of a lexical
??>> variable (binding).

T> If I am using it local to that lexical variable - why not?

It simply has nothing to do with lexical variable.
Why do you think SYMBOL-VALUE should be related to variable?
It is not called VARIABLE-VALUE, right?

What is variable is defined in section "3.1.2.1.1 Symbols as Forms":
http://clhs.lisp.se/Body/03_abaa.htm
---
If a form is a symbol, then it is either a symbol macro or a variable.
---

In form (symbol-value 'foo) there is no reference to variable foo, (QUOTE
FOO) is symbol itself, not variable denoted by it.

So compiler just does not recognize it as variable access and thus it won't
generate code which would access that variable.

In theory you could write a compiler which would recognize (symbol-value
'foo) as a variable access, but then it would be incompatible with CL.

??>> It is called lexical because it only makes sense within textual piece
??>> of code where it is defined.

T> OK. So I call (setf (symbol-function 'my-lexical-var) 10) within
T> textual piece of code where it is defined. What is the reason that
T> doesn't work since according to Ankur - my-lexical-var - is a symbol.

Compiler would recognize (foo ...) as use of function foo. It would also
recognize (function foo) as a form that must return function object.
It does not recognize (symbol-function 'foo) being anyhow related to local
function foo.

Do you think compiler should recognize string "FOO" as being a reference to
local function foo? That would be silly, won't it?
So why would it consider (symbol-function (find-symbol "FOO")) as a
reference?

??>> For example, compiler might decide that CPU register EAX will hold
??>> value of LOCAL-VALUE. Of course you can write (setf (symbol-function
??>> 'local-value) 'foo) but it definitely won't affect value of register
??>> EAX.

T> If register EAX is holding a value, it isn't holding a symbol.

CPU registers work on a different level of abstraction.

T> According to the CLHS
T>
http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm#symbol
T> a symbol has five attributes.

T> _IF_ local-value is a symbol. What is stored in register EAX is a value
T> referred to by one of the five attributes of a symbol.

It IS NOT a symbol. Its NAME is a symbol.

Is it that hard to recognize difference between NAME of a thing and thing
ITSELF?

TheFlyingDutchman is your name. If I'll punch it you won't feel that, right?

Likewise, if you "punch" symbol foo with (symbol-value 'foo) lexical
variable just won't feel it because it is a different thing.

You have a wrong impression that everything works through symbols in CL. It
is just wrong. Symbols are used at time of compilation, and sometimes in
runtime.
But after code is compiled typically it is not related to symbols used in
code.

One last analogy: let's say you've got a textual description of what you
need to draw "draw a blue bird" and then you draw a blue bird. Now if
somebody replaces word "blue" with "red", will your painting change? Fucking
no, it will stay blue, because painting has no relationship whatsoever with
textual description used to draw it after it is painted.
This is exactly how lexical bindings work -- they have no relationship
whatsoever with code used to describe them after it is compiled. (At least
in semantics described in CL standard.)

Anticomuna

unread,
Apr 19, 2011, 11:33:05 PM4/19/11
to

The symbol that holds the function and the function itself are two
different objects altogether. So much so that you can retrieve the
function value and assign it to some other variable.

If it isn't so in Common Lisp then it is the most counter-intuitive,
contorted, mind-numbingly stupid crap ever made into a programming
language.

Really, it is mind-bogling.

Being able to change lexical bindings for functions is a natural
assumption given how variables work. It seems like the creators of
this thing are trying to screw with the developer.

Anticomuna

unread,
Apr 19, 2011, 11:42:51 PM4/19/11
to
On 15 abr, 08:54, "Captain Obvious" <udode...@users.sourceforge.net>
wrote:

>  A> Well, this is stupid. My implementation updates the lexical
>  A> environment, if there's a function that uses the same symbol.
>
> Well, this is stupid.
>
> http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/mac...

> Defines a new function named function-name in the global environment.

Common Lisp is not an end in itself. A programming language is only as
good as it is useful.

Changing things that don't make sense is a necessity. Stupid would be
to blindly follow some standard, with stupidities and all.

Pascal J. Bourguignon

unread,
Apr 20, 2011, 12:23:59 AM4/20/11
to
Anticomuna <ts.con...@uol.com.br> writes:

> On 15 abr, 07:58, Tim Bradshaw <t...@tfeb.org> wrote:
>> On 2011-04-15 10:33:41 +0100, Anticomuna said:
>>
>> > It is a variable that points to a function.
>>
>> No, it's not, not in common lisp.  It is in scheme or any other lisp-1.
>
> The symbol that holds the function and the function itself are two
> different objects altogether. So much so that you can retrieve the
> function value and assign it to some other variable.
>
> If it isn't so in Common Lisp then it is the most counter-intuitive,
> contorted, mind-numbingly stupid crap ever made into a programming
> language.
>
> Really, it is mind-bogling.

What's mind-bogling is to hear people who don't know speak...

(defun fun (x) `(i am having fun with ,x))
(setf (symbol-function 'geez) (symbol-function 'fun))
(geez 'newbies)
--> (i am having fun with newbies)

RG

unread,
Apr 20, 2011, 1:05:13 AM4/20/11
to
In article <87ipu9k...@kuiper.lan.informatimago.com>,

"Pascal J. Bourguignon" <p...@informatimago.com> wrote:

> Anticomuna <ts.con...@uol.com.br> writes:
>
> > On 15 abr, 07:58, Tim Bradshaw <t...@tfeb.org> wrote:
> >> On 2011-04-15 10:33:41 +0100, Anticomuna said:
> >>
> >> > It is a variable that points to a function.
> >>
> >> No, it's not, not in common lisp.  It is in scheme or any other lisp-1.
> >
> > The symbol that holds the function and the function itself are two
> > different objects altogether. So much so that you can retrieve the
> > function value and assign it to some other variable.
> >
> > If it isn't so in Common Lisp then it is the most counter-intuitive,
> > contorted, mind-numbingly stupid crap ever made into a programming
> > language.
> >
> > Really, it is mind-bogling.
>
> What's mind-bogling is to hear people who don't know speak...
>
> (defun fun (x) `(i am having fun with ,x))
> (setf (symbol-function 'geez) (symbol-function 'fun))
> (geez 'newbies)
> --> (i am having fun with newbies)

Actually, Anticomuna has a point.

> Being able to change lexical bindings for functions is a natural
> assumption given how variables work.

You can assign symbol value bindings and symbol function bindings. You
can assign lexical value bindings. It seems reasonable that you should
be able to assign lexical function bindings. But you can't. It is
indeed counter-intuitive. (I'll refrain from passing judgement on
"mind-numbingly stupid crap.")

rg

Alessio Stalla

unread,
Apr 20, 2011, 4:26:28 AM4/20/11
to
On 20 Apr, 07:05, RG <rNOSPA...@flownet.com> wrote:
> In article <87ipu9k0tc....@kuiper.lan.informatimago.com>,

I agree with your opinion. But I have never felt the need to be able
to assign a new value to a local function binding (I think it would
make code harder to read), and I can imagine it could lead to counter-
intuitive behaviour for inlined functions. If you want, you can still
bind a local variable to a function and use funcall/apply, and assign
happily every time you want. In other words, yes, it's an
inconsistency, but a minor one and it has reasons to be like it is.

Alessio

Tim Bradshaw

unread,
Apr 20, 2011, 4:48:09 AM4/20/11
to
On 2011-04-16 16:56:38 +0100, TheFlyingDutchman said:

> I have created a symbol "global-value" that I believe has 5 slots. One
> to point to the symbol name, another to point to a value, one to point
> to a function, one to point to a property list and one to point to a
> package name.

I'm not going to try and answer the question you're asking directly,
but a good way to think about this is to consider what a multithreaded
CL implementation does. This is obviously not standardised, but I
suspect they all do the same thing (since, modulo small variations,
there's really only one sensible behaviour here, I think). For
instannce imagine code like this:

(defvar *x* 'global)

...
(let ((*x* ...))
(symbol-function '*x*))
...

Where the rebinding of *x* happens in multiple threads, concurrently.
Where are the slots of *x* now?

Captain Obvious

unread,
Apr 20, 2011, 5:10:03 AM4/20/11
to
A> Common Lisp is not an end in itself. A programming language is only as
A> good as it is useful.

It is useful enough for me.

A> Changing things that don't make sense is a necessity. Stupid would be
A> to blindly follow some standard, with stupidities and all.

I don't see how implementing this "feature" helps anybody.
Dynamic redefinition is not considered a good style. In more progressive
functional programming languages (e.g. Haskell) there is no even analog of
SETQ.
OTOH if local functions can be changed in runtime certain optimizations are
not possible.

So this change will be a move from clean and fast Lisp to messy and slow
one. It is a change in a wrong direction.

Anticomuna

unread,
Apr 20, 2011, 8:01:08 AM4/20/11
to
On 20 abr, 06:10, "Captain Obvious" <udode...@users.sourceforge.net>
wrote:

Someone who wants immutable state wouldn't be using a language like
Lisp in the first place. So the more "progressive" argument is BS,
especially because "progressive" is your opinion. I don't think it is
progressive at all, it is the wrong direction.

Besides, optimization is the implementor's business, not the user's.
The user shouldn't be forced to work in a stupid way because of such
details. Making people's life easier is what computers are about, and
this is the same reason we have GUIs and graphical development
environments there days instead of the command line and vi, even if it
uses a lot more memory.

Alessio Stalla

unread,
Apr 20, 2011, 12:35:44 PM4/20/11
to
On 20 Apr, 14:01, Anticomuna <ts.concei...@uol.com.br> wrote:
> On 20 abr, 06:10, "Captain Obvious" <udode...@users.sourceforge.net>
> wrote:
>
>
>
>
>
>
>
>
>
> >  A> Common Lisp is not an end in itself. A programming language is only as
> >  A> good as it is useful.
>
> > It is useful enough for me.
>
> >  A> Changing things that don't make sense is a necessity. Stupid would be
> >  A> to blindly follow some standard, with stupidities and all.
>
> > I don't see how implementing this "feature" helps anybody.
> > Dynamic redefinition is not considered a good style. In more progressive
> > functional programming languages (e.g. Haskell) there is no even analog of
> > SETQ.
> > OTOH if local functions can be changed in runtime certain optimizations are
> > not possible.
>
> > So this change will be a move from clean and fast Lisp to messy and slow
> > one. It is a change in a wrong direction.
>
> Someone who wants immutable state wouldn't be using a language like
> Lisp in the first place. So the more "progressive" argument is BS,
> especially because "progressive" is your opinion. I don't think it is
> progressive at all, it is the wrong direction.

Common Lisp has chosen to separate conceptually functions from
variables. Whether this is a good idea or not is a matter of endless
debates, but the decision has been made nonetheless, a long time ago,
and it cannot be changed (at least while remaining in the scope of
what Common Lisp is). That certain behaviors are sported by variables
and not functions and vice-versa is a product of this fundamental
distinction. Some view these differences as inconsistencies, others
view them as convenient features and potential sources of
optimizations. The bottom line is that there's no clear "right" and
"wrong" position - each has its pros and cons and which one is better
depends on the kind of code you typically write.

> Besides, optimization is the implementor's business, not the user's.
> The user shouldn't be forced to work in a stupid way because of such
> details. Making people's life easier is what computers are about, and
> this is the same reason we have GUIs and graphical development
> environments there days instead of the command line and vi, even if it
> uses a lot more memory.

You consider it a stupid way, I instead don't find it a great loss if
I'm not able to change local function bindings, I don't recall a case
when I would have needed it. Who's right? (That's a rhetorical
question).

Cheers,
Alessio

RG

unread,
Apr 20, 2011, 12:50:52 PM4/20/11
to
In article
<aae8102c-6b68-416b...@18g2000prd.googlegroups.com>,
Alessio Stalla <alessi...@gmail.com> wrote:

I'm not making any judgement on whether this design decision was good or
bad. My only point is that it's unfair to criticize someone for being
confused by the fact that three of the four combinations of
lexical/dynamic and value/function are assignable and one is not.

rg

Thomas A. Russ

unread,
Apr 20, 2011, 12:32:00 PM4/20/11
to
Anticomuna <ts.con...@uol.com.br> writes:

> Being able to change lexical bindings for functions is a natural
> assumption given how variables work. It seems like the creators of
> this thing are trying to screw with the developer.

Well, I happen to think that one point of using local, lexical functions
is to make it easy to see what function is being referred to by a piece
of code. Considering that any such function binding is by definition
lexical, it is much clearer to me to have two different function names
if you really have two different functions that you want to use.

Why do you think that the following too hard?
(flet ((f (x) ...)
(g (x) ...))
....
(f 23)
...
(g 42))

In any case, if you really, really, really want to have dynamically
rebindable lexical functions you can always create your own binding
construct and infrastructure using the macro system. Here is a simple
sketch of how that might look:

(defvar *dynamic-flet-dictionary* nil)

(defmacro dynamic-flet ((&rest functions) &body body)
`(progn
,@(loop for func in functions
collect `(push (cons ',(first func)
(lambda ,@(rest func)))
*dynamic-flet-dictionary*))
(unwind-protect
(flet ,(loop for func in functions
collect `(,(first func) ,(second func)
(funcall (cdr (assoc ',(first func)
*dynamic-flet-dictionary*))
,@(second func))))
,@body)
(loop repeat ,(length functions)
do (pop *dynamic-flet-dictionary*)))))


(defmacro rebind (name var-list &body body)
`(if (assoc ',name *dynamic-flet-dictionary*)
(setf (cdr (assoc ',name *dynamic-flet-dictionary*))
(lambda ,var-list ,@body))
(error "~A is not bound" ',name)))

(dynamic-flet ((f (x y) (+ x y))
(g (x y z) (list x y z)))
(print (f 2 3))
(print (f 3 4))
(rebind f (x y) (* x y))
(print (f 2 3))
(print (g 1 2 3))
(rebind g (x y z) (list z y x))
(g 1 2 3))


This can be cleaned up a bit and made more robust with UNWIND-PROTECT,
but the general idea is here.

--
Thomas A. Russ, USC/Information Sciences Institute

WJ

unread,
Apr 20, 2011, 2:53:31 PM4/20/11
to
RG wrote:

Scheme:

(let ((func1 (lambda () (display "Hi from func1\n"))))
(func1)
(set! func1 (lambda () (display "Hello!\n")))
(func1))

==>

Hi from func1
Hello!

TheFlyingDutchman

unread,
Apr 20, 2011, 3:31:36 PM4/20/11
to
>
> Well, I happen to think that one point of using local, lexical functions
> is to make it easy to see what function is being referred to by a piece
> of code.  Considering that any such function binding is by definition
> lexical, it is much clearer to me to have two different function names
> if you really have two different functions that you want to use.

I don't think that seeing more easily what function is being referred
to should be a rationale for using flet/labels. If a function has
capability for general usage it should be global - so that it can
receive general usage and reuse. If it can't be made global due to a
lack of time to generalize it or an inherent specificity
characteristic, then it should be local to avoid polluting the global
arena with something that only has local usefulness.

The fact that Common Lisp allows the rebinding of global functions
seems to cancel out the argument that Common Lisp shouldn't allow
rebinding local functions because it is confusing, unless it is
accompanied by an argument that Common Lisp shouldn't allow rebinding
global functions as well. On the basis that rebinding a global
function doesn't seem any less confusing than rebinding a local one.

Pascal J. Bourguignon

unread,
Apr 20, 2011, 3:37:47 PM4/20/11
to
"WJ" <w_a_...@yahoo.com> writes:

>
> Scheme:
>
> (let ((func1 (lambda () (display "Hi from func1\n"))))
> (func1)
> (set! func1 (lambda () (display "Hello!\n")))
> (func1))
>
> ==>
>
> Hi from func1
> Hello!

Common Lisp:

(let ((func1 (lambda () (format t "Hi from func1~%"))))
(funcall func1)
(setf func1 (lambda () (format t "Hello!~%")))
(funcall func1))

;; prints:
Hi from func1
Hello!
;; --> NIL

TheFlyingDutchman

unread,
Apr 20, 2011, 4:09:57 PM4/20/11
to
On Apr 17, 8:28 am, "Captain Obvious" <udode...@users.sourceforge.net>
wrote:

> symbol-value can be used to get and set symbol's value.
> But symbol's value becomes tied to variable with corresponding name only
> when variable is declared special.

Can you give an example with code of a symbol's value being tied to a
variable? It appears you are talking about 4 distinct things and I
can't conceptualize what is going on.

1) symbol
2) symbol's value
3) variable
4) variable name

>
>  ??>> Although in most implementations you can use it as a variable even
>  ??>> without a declaim, but then behaviour is not specified by standard.
>
>  T> Are you saying that some implementations would not allow
>
>  T> (setq my-var 10)
>
>  T> as the first reference to my-var?
>
> They might, in theory. SBCL generates warning.
> Note that variable you get in this case might be not special, it might be
> something like a "global lexical" -- it has value in global context, but it
> can be shadowed lexically.
> This behaviour is not specified by standard, thus it is better to avoid
> this.

Can't any symbol be "shadowed lexically"?

(defvar a 10)

(let ( (a 20) ) (print a)) => 20

(defun hi () (print "hi"))

(flet ( (hi () (print "bye"))) (hi)) => "bye"


>
>  ??>> Yes, you can do that, but it has nothing to do with value of a lexical
>  ??>> variable (binding).
>
>  T> If I am using it local to that lexical variable - why not?
>
> It simply has nothing to do with lexical variable.
> Why do you think SYMBOL-VALUE should be related to variable?
> It is not called VARIABLE-VALUE, right?

According to Ankur, (let ( (my-var 10) ) ), my-var is a symbol. Why
shouldn't I expect symbol-value to work on a symbol?

>
> What is variable is defined in section "3.1.2.1.1 Symbols as Forms":http://clhs.lisp.se/Body/03_abaa.htm
> ---
> If a form is a symbol, then it is either a symbol macro or a variable.
> ---
>
> In form (symbol-value 'foo) there is no reference to variable foo, (QUOTE
> FOO) is symbol itself, not variable denoted by it.
>
> So compiler just does not recognize it as variable access and thus it won't
> generate code which would access that variable.

Are you using "variable" synonomously with "symbol value"?

>
> In theory you could write a compiler which would recognize (symbol-value
> 'foo) as a variable access, but then it would be incompatible with CL.

Why do you say that (symbol-value 'foo) is doing in Common Lisp?

>
>  ??>> It is called lexical because it only makes sense within textual piece
>  ??>> of code where it is defined.
>
>  T> OK. So I call (setf (symbol-function 'my-lexical-var) 10) within
>  T> textual piece of code where it is defined. What is the reason that
>  T> doesn't work since according to Ankur - my-lexical-var - is a symbol.
>
> Compiler would recognize (foo ...) as use of function foo. It would also
> recognize (function foo) as a form that must return function object.
> It does not recognize (symbol-function 'foo) being anyhow related to local
> function foo.
>
> Do you think compiler should recognize string "FOO" as being a reference to
> local function foo? That would be silly, won't it?
> So why would it consider (symbol-function (find-symbol "FOO")) as a
> reference?

The compiler certainly recognizes "myvar" as being the local reference
if I do

(defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20

How was the compiler able to recognize myvar as being the local one
when there were two to choose from?

>
>  T> According to the CLHS

>  T>http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm#sy...


>  T> a symbol has five attributes.
>
>  T>  _IF_ local-value is a symbol. What is stored in register EAX is a value
>  T> referred to by one of the five attributes of a symbol.
>
> It IS NOT a symbol. Its NAME is a symbol.
>
> Is it that hard to recognize difference between NAME of a thing and thing
> ITSELF?

I think we agree a symbol is a structure with five slots. One points
to something called the "symbol value". One points to something called
the "symbol name". Is that what you are referring to when you talk
about "thing itself" and "name"?

>
> TheFlyingDutchman is your name. If I'll punch it you won't feel that, right?
>
> Likewise, if you "punch" symbol foo with (symbol-value 'foo) lexical
> variable just won't feel it because it is a different thing.

Do you disagree with the statement that what is defined with a let is
a symbol and what is defined with flet is a symbol?

>
> You have a wrong impression that everything works through symbols in CL. It
> is just wrong. Symbols are used at time of compilation, and sometimes in
> runtime.

I asked what was defined by flet and let. I was told there were
symbols. It's not hard to get the idea that everything works through
symbols if everything is a symbol.


> But after code is compiled typically it is not related to symbols used in
> code.
>
> One last analogy: let's say you've got a textual description of what you
> need to draw "draw a blue bird" and then you draw a blue bird. Now if
> somebody replaces word "blue" with "red", will your painting change? Fucking
> no, it will stay blue, because painting has no relationship whatsoever with
> textual description used to draw it after it is painted.
> This is exactly how lexical bindings work -- they have no relationship
> whatsoever with code used to describe them after it is compiled. (At least
> in semantics described in CL standard.)

I found this statement ( http://clhs.lisp.se/Body/t_symbol.htm#symbol
):

"Symbols are used as identifiers for lexical variables and lexical
function definitions, but in that role, only their object identity is
significant. Common Lisp provides no operation on a symbol that can
have any effect on a lexical variable or on a lexical function
definition."

This statement follows a blurb about how a symbol has 5 cells. It
would be nice if the person who wrote the above statement had seen fit
to explain how the phrase "only their object identity is significant"
relates to a structure of five cells which are used to hold the
address of 5 different objects and for which there are multiple
functions to deal with what is referred to by those 5 cells.

paul-d...@sbcglobal.net

unread,
Apr 20, 2011, 5:13:39 PM4/20/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> The fact that Common Lisp allows the rebinding of global functions
> seems to cancel out the argument that Common Lisp shouldn't allow
> rebinding local functions because it is confusing, unless it is
> accompanied by an argument that Common Lisp shouldn't allow rebinding
> global functions as well. On the basis that rebinding a global
> function doesn't seem any less confusing than rebinding a local one.

But would you want to use a language that required you to restart the
world every time you changed a function? It would be less confusing, but
not worth it at all.

Alessio Stalla

unread,
Apr 20, 2011, 6:15:45 PM4/20/11
to
On 20 Apr, 23:13, paul-donne...@sbcglobal.net wrote:

Additionally, while (re)defining global functions can happen anywhere
and anytime during the execution of the program, lexical function
redefinition - were it possible - could only happen in the lexical
scope of the definition and in the dynamic scope of a given call to
the defining function. This has the implication that a local function
could be only redefined as part of a procedural algorithm - do x, call
f1, do y, set f1 to f2, do z, call f1 (now referring to f2), do ...
Instead, the redefinition of a global function is not tied to this
kind of (ab)use, it can be used more generally to update the running
Lisp image, e.g. to fix a bug or to implement new behavior.
Variables in principle also suffer from the same problem, but in
practice assignment to variables is too useful to be removed - or at
least the designers and users of Common Lisp believe it, at least
while programming in Common Lisp ;) - and anyway if it were removed,
it would create a fundamental change in the spirit of the language,
and would need entirely new tools and abstractions. Local function
redefinition is much, much less needed.
Last but not least, if you really want redefinable local functions, I
suspect that you can get them with some clever macrology - as it
(almost) always happens in Lisp. But I haven't thought too deep about
that.

Alessio

TheFlyingDutchman

unread,
Apr 20, 2011, 7:33:21 PM4/20/11
to
On Apr 20, 2:13 pm, paul-donne...@sbcglobal.net wrote:

I am not sure I understand what you are referring to. I guess the
situation involves REPL tinkering with a desire to change a function
that has already been loaded. Do you need (setf (symbol-function
'function-a) ... to do that? Can't you just retype in function-a and
load it again?

To be clear, what I am referring to is when the function cell of
symbol - function-a - is defined one way with a defun, and then
changed at runtime to refer to another function. Making debugging and
program comprehension more difficult since you have to both see that
it can be changed, and also know whether it was changed, anytime you
look at a call to what is referred to by the function cell of symbol
function-a.

Although, I don't know that it makes sense to change a symbol function
cell value to a function object that isn't very similar to the
original function - just more tuned to the current situation or user.

TheFlyingDutchman

unread,
Apr 20, 2011, 7:39:58 PM4/20/11
to
>
> Additionally, while (re)defining global functions can happen anywhere
> and anytime during the execution of the program, lexical function
> redefinition - were it possible - could only happen in the lexical
> scope of the definition and in the dynamic scope of a given call to
> the defining function. This has the implication that a local function
> could be only redefined as part of a procedural algorithm - do x, call
> f1, do y, set f1 to f2, do z, call f1 (now referring to f2), do ...

Can't anything that could be done with flet local function
redefinition be done now with let and funcall. Is using let and
funcall abuse?

TheFlyingDutchman

unread,
Apr 20, 2011, 8:03:42 PM4/20/11
to
On Apr 20, 1:48 am, Tim Bradshaw <t...@tfeb.org> wrote:
> On 2011-04-16 16:56:38 +0100, TheFlyingDutchman said:
>
> > I have created a symbol "global-value" that I believe has 5 slots. One
> > to point to the symbol name, another to point to a value, one to point
> > to a function, one to point to a property list and one to point to a
> > package name.
>
> I'm not going to try and answer the question you're asking directly,
> but a good way to think about this is to consider what a multithreaded
> CL implementation does.  This is obviously not standardised, but I
> suspect they all do the same thing (since, modulo small variations,
> there's really only one sensible behaviour here, I think).  For
> instannce imagine code like this:
>
> (defvar *x* 'global)

How is this is represented internally. Are there now two entries in a
symbol table (or similar structure) for "*x*" and "global"? Does the
entry for "*x*" point to a 5 cell structure known as a symbol and
likewise for the "global" entry. Does the "symbol value cell" of the
*x* symbol structure point to the symbol structure for the "global"
symbol?

Pascal J. Bourguignon

unread,
Apr 20, 2011, 8:36:09 PM4/20/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> On Apr 17, 8:28 am, "Captain Obvious" <udode...@users.sourceforge.net>
> wrote:
>> symbol-value can be used to get and set symbol's value.
>> But symbol's value becomes tied to variable with corresponding name only
>> when variable is declared special.
>
> Can you give an example with code of a symbol's value being tied to a
> variable? It appears you are talking about 4 distinct things and I
> can't conceptualize what is going on.
>
> 1) symbol
> 2) symbol's value
> 3) variable
> 4) variable name


(defvar *a-special-variable* 42)

(defun example ()
(let ((a-variable 88))
(setf (symbol-value 'a-variable) "I am a symbol value")
(format t "A symbol is: ~S~%" 'a-variable)
(format t "A symbol value is: ~S~%" (symbol-value 'a-variable))
(format t "A variable named by the symbol ~S~%" 'a-variable)
(format t "A variable value is: ~S~%" a-variable)
(format t "Another symbol is: ~S~%" '*a-special-variable*)
(format t "Another symbol value is: ~S~%" (symbol-value '*a-special-variable*))
(format t "Another variable named by the symbol ~S~%" '*a-special-variable*)
(format t "Another variable value is: ~S~%" *a-special-variable*)
(values)))


CL-USER> (example)
A symbol is: A-VARIABLE
A symbol value is: "I am a symbol value"
A variable named by the symbol A-VARIABLE
A variable value is: 88
Another symbol is: *A-SPECIAL-VARIABLE*
Another symbol value is: 42
Another variable named by the symbol *A-SPECIAL-VARIABLE*
Another variable value is: 42
; No value

Notice variables are not first class objects, only symbols and values.
So we cannot print a variable, only the name of a variable (which is a
symbol), or the value of a variable.

> Can't any symbol be "shadowed lexically"?

If you start using loosy terminology, then 2=0.


> (defvar a 10)
>
> (let ( (a 20) ) (print a)) => 20

That's not the point. The point is that:

(defvar a 10)

(defun f ()
(print a))

(let ((a 20))
(f))

;; prints:
20
;; --> 20


Or:


(defun g ()
(declare (special b))
(print a))

(let ((b 20))
(declare (special b))
(g))

;; prints:
20
;; --> 20


> According to Ankur, (let ( (my-var 10) ) ), my-var is a symbol. Why
> shouldn't I expect symbol-value to work on a symbol?

Because symbols may be unbound (have no value), and in this case,
symbol-value must signal an error.


CL-USER> (ignore-errors (let ((my-var 10)) (symbol-value 'my-var)))
NIL
#<SYSTEM::SIMPLE-UNBOUND-VARIABLE #x000334342AE0>

>> What is variable is defined in section "3.1.2.1.1 Symbols as Forms":http://clhs.lisp.se/Body/03_abaa.htm
>> ---
>> If a form is a symbol, then it is either a symbol macro or a variable.
>> ---
>>
>> In form (symbol-value 'foo) there is no reference to variable foo, (QUOTE
>> FOO) is symbol itself, not variable denoted by it.
>>
>> So compiler just does not recognize it as variable access and thus it won't
>> generate code which would access that variable.
>
> Are you using "variable" synonomously with "symbol value"?

No, he is not. Try to understand!

>> In theory you could write a compiler which would recognize (symbol-value
>> 'foo) as a variable access, but then it would be incompatible with CL.
>
> Why do you say that (symbol-value 'foo) is doing in Common Lisp?

He isn't saying that "(symbol-value 'foo) is doing in Common Lisp"
because that sentence is meaningless in English.

Why do you ask meaningless and ungrammatical questions?

> The compiler certainly recognizes "myvar" as being the local reference
> if I do
>
> (defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20
>
> How was the compiler able to recognize myvar as being the local one
> when there were two to choose from?

The fact that there is a local dynamic binding is irrelevant to the way
dynamic binding works.

Once you've used defvar, the symbol is declared special, and all the
bindings occuring to this symbol are dynamic bindings. There's a single
dynamic binding valid at any TIME. It doesn't depend on WHERE it is,
local or global.


Don't you know the difference between time and space?

dynamic <-> time
lexical <-> space


"Local" is a space criteria. Try "present" for time.


>> It IS NOT a symbol. Its NAME is a symbol.
>>
>> Is it that hard to recognize difference between NAME of a thing and thing
>> ITSELF?
>
> I think we agree a symbol is a structure with five slots. One points
> to something called the "symbol value". One points to something called
> the "symbol name". Is that what you are referring to when you talk
> about "thing itself" and "name"?

No. He was asking the question in general. But you could apply it in
particular, and in this case, the "thing itself" refers to the variable,
which is not its name, the symbol.

Can't you understand that symbols are not variables, but the names of
the variables?

> Do you disagree with the statement that what is defined with a let is
> a symbol and what is defined with flet is a symbol?

Yes, we do disagree.

Try to read the description of LET in CLHS, and tell us if you see the
word "symbol".

>> You have a wrong impression that everything works through symbols in CL. It
>> is just wrong. Symbols are used at time of compilation, and sometimes in
>> runtime.
>
> I asked what was defined by flet and let. I was told there were
> symbols.


This is wrong. LET defines variables, FLET defines functions.


> It's not hard to get the idea that everything works through
> symbols if everything is a symbol.

That's why you should read the CLHS first.

> I found this statement ( http://clhs.lisp.se/Body/t_symbol.htm#symbol
> ):
>
> "Symbols are used as identifiers for lexical variables and lexical
> function definitions, but in that role, only their object identity is
> significant. Common Lisp provides no operation on a symbol that can
> have any effect on a lexical variable or on a lexical function
> definition."
>
> This statement follows a blurb about how a symbol has 5 cells. It
> would be nice if the person who wrote the above statement had seen fit
> to explain how the phrase "only their object identity is significant"
> relates to a structure of five cells which are used to hold the
> address of 5 different objects and for which there are multiple
> functions to deal with what is referred to by those 5 cells.

But since identity doesn't relate to structure, what do you want us to
explain?

How can we explain something that doesn't exist?

What can I tell you about the odd multiples of two? That they are blue?
That they can beat you in the face? That they can go faster than light?
How are you smarter knowing all these facts about an entity that doesn't
exist?

My advice would be for you to learn some basic logic...

Thomas A. Russ

unread,
Apr 20, 2011, 9:33:06 PM4/20/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:
> The compiler certainly recognizes "myvar" as being the local reference
> if I do
>
> (defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20
>
> How was the compiler able to recognize myvar as being the local one
> when there were two to choose from?

Actually it doesn't. It uses the special variables, as the earlier
example I gave showed. It is just that LET interacts with special
variables bindings by binding and restoring the value.after exiting the
let block.

You can generate even more amazing examples:

(defvar *a* 10)
(defun foo () (setq *a* -10))
(print *a*)
(let ((*a* 20))
(print *a*)
(foo)
(print *a*))
(print *a*)

Thomas A. Russ

unread,
Apr 20, 2011, 9:37:48 PM4/20/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> The fact that Common Lisp allows the rebinding of global functions
> seems to cancel out the argument that Common Lisp shouldn't allow
> rebinding local functions because it is confusing, unless it is
> accompanied by an argument that Common Lisp shouldn't allow rebinding
> global functions as well. On the basis that rebinding a global
> function doesn't seem any less confusing than rebinding a local one.

Well, I would think that changing the value global functions at run-time
would be a bad idea because it would be confusing. The ability to do it
stems in part from a desire to
(a) Promote an interactive development cycle. So making changes
during development when there is an intent to replace the function
with a better one is one thing. Designing a system where you rely
on dynamic changes of function definition as part of the design
just seems crazy to me.
(b) It is a consequence of making the SYMBOL-FUNCTION assignable in the
first place. This does allow the generation and run-time setting of
the value, and it would have been tough to allow you to set it just
once. That would also conflict with goal (a).

But again, changing the meaning of functions at run time is something
you would not really want to do on a regular basis, simply because it is
confusing. But then again, CommonLisp's design philosophy is to give
you the rope and trust you to use it wisely.

Thomas A. Russ

unread,
Apr 20, 2011, 9:27:11 PM4/20/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:


> Can't any symbol be "shadowed lexically"?
>
> (defvar a 10)
> (let ((a 20)) (print a)) => 20
>

But not if you make it globally special:

(defun foo () (setq a -10))
(let ((a 20)) (foo) (print a))

This hardly seems like lexical shadowing. (This is related to globally
special variables being always special).

> (defun hi () (print "hi"))
>
> (flet ( (hi () (print "bye"))) (hi)) => "bye"

There is no equivalent for lexical functions.

TheFlyingDutchman

unread,
Apr 21, 2011, 1:42:50 AM4/21/11
to
On Apr 20, 6:27 pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:

> TheFlyingDutchman <zzbba...@aol.com> writes:
> > Can't any symbol be "shadowed lexically"?
>
> > (defvar a 10)
> > (let ((a 20)) (print a))   => 20
>
> But not if you make it globally special:
>
> (defun foo () (setq a -10))
> (let ((a 20)) (foo) (print a))

It prints 20. I don't see what is different. (print a) prints the
local a not the global one. Maybe I should ask for a definition of the
term "shadowed lexically". I thought it was saying the local name
"blocked out" the global one.


Regarding special and special variables, the CLHS has this glossary
definition:
Special variable n. Trad. a dynamic variable.

I don't understand the meaning of globally special. If that translates
to "globally dynamic", I am still not familiar with that term.

WJ

unread,
Apr 21, 2011, 1:51:56 AM4/21/11
to
TheFlyingDutchman wrote:

> (flet ( (function1 () (format t "hi from function1~%")))

COBOL-Lispers for some reason think that they have to use
"format" in order to print to the screen.

* (write-line "foo")
foo

TheFlyingDutchman

unread,
Apr 21, 2011, 2:14:55 AM4/21/11
to
On Apr 20, 6:37 pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:

> TheFlyingDutchman <zzbba...@aol.com> writes:
> > The fact that Common Lisp allows the rebinding of global functions
> > seems to cancel out the argument that Common Lisp shouldn't allow
> > rebinding local functions because it is confusing, unless it is
> > accompanied by an argument that Common Lisp shouldn't allow rebinding
> > global functions as well. On the basis that rebinding a global
> > function doesn't seem any less confusing than rebinding a local one.
>
> Well, I would think that changing the value global functions at run-time
> would be a bad idea because it would be confusing. The ability to do it
> stems in part from a desire to
> (a) Promote an interactive development cycle. So making changes
> during development when there is an intent to replace the function
> with a better one is one thing. Designing a system where you rely
> on dynamic changes of function definition as part of the design
> just seems crazy to me.

It could be used to eliminate if/case statements and passed
parameters. You would defun something like (spell-check) but give it
no functionality. Then defun (spell-check-french) (spell-check-
german), (spell-check-klingon) and at runtime assign one of them to
spell-check rather than doing (setf *language* +GERMAN+) and calling
(spell-check .. *language*)

It would seem that you could use a REPL for development and modify
functions without having to have the capability to be able to (setf
(symbol-function ... At least I think other languages have REPLs and
don't have an equivalent.

> (b) It is a consequence of making the SYMBOL-FUNCTION assignable in the
> first place. This does allow the generation and run-time setting of
> the value, and it would have been tough to allow you to set it just
> once. That would also conflict with goal (a).

Couldn't there be multiple settings via (defun..)? Other languages
have REPLs but I don't think they have the equivalent of (setf (symbol-
function...).


> But again, changing the meaning of functions at run time is something
> you would not really want to do on a regular basis, simply because it is
> confusing. But then again, CommonLisp's design philosophy is to give
> you the rope and trust you to use it wisely.

They did draw a line at allowing rebinding of flet stuff.

paul-d...@sbcglobal.net

unread,
Apr 21, 2011, 2:15:37 AM4/21/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> On Apr 20, 2:13 pm, paul-donne...@sbcglobal.net wrote:
>> TheFlyingDutchman <zzbba...@aol.com> writes:
>> > The fact that Common Lisp allows the rebinding of global functions
>> > seems to cancel out the argument that Common Lisp shouldn't allow
>> > rebinding local functions because it is confusing, unless it is
>> > accompanied by an argument that Common Lisp shouldn't allow rebinding
>> > global functions as well. On the basis that rebinding a global
>> > function doesn't seem any less confusing than rebinding a local one.
>>
>> But would you want to use a language that required you to restart the
>> world every time you changed a function? It would be less confusing, but
>> not worth it at all.
>
> I am not sure I understand what you are referring to. I guess the
> situation involves REPL tinkering with a desire to change a function
> that has already been loaded. Do you need (setf (symbol-function
> 'function-a) ... to do that? Can't you just retype in function-a and
> load it again?

There's no difference between those two scenarios. I suppose it would be
possible to make DEFUN the only interface for defining and redefining
functions, but what difference would that make? You're still replacing
function definitions.

> To be clear, what I am referring to is when the function cell of
> symbol - function-a - is defined one way with a defun, and then
> changed at runtime to refer to another function. Making debugging and
> program comprehension more difficult since you have to both see that
> it can be changed, and also know whether it was changed, anytime you
> look at a call to what is referred to by the function cell of symbol
> function-a.

How would you disallow this but allow loading new definitions when the
code changes?

TheFlyingDutchman

unread,
Apr 21, 2011, 2:28:21 AM4/21/11
to
On Apr 20, 6:33 pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:

> TheFlyingDutchman <zzbba...@aol.com> writes:
> > The compiler certainly recognizes "myvar" as being the local reference
> > if I do
>
> > (defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20
>
> > How was the compiler able to recognize myvar as being the local one
> > when there were two to choose from?
>
> Actually it doesn't.  It uses the special variables, as the earlier
> example I gave showed.  It is just that LET interacts with special
> variables bindings by binding and restoring the value.after exiting the
> let block.

So if have
(let ( (a 10) ...

and there is no global a, let makes a global symbol a, and assigns to
it's variable cell, and then after it is done it nulls out the
variable cell?

>
> You can generate even more amazing examples:
>
> (defvar *a* 10)
> (defun foo () (setq *a* -10))

> (print *a*) ; 1
> (let ((*a* 20))
>   (print *a*) ; 2
>   (foo)
>   (print *a*)) ; 3
> (print *a*) ; 4
>
I have no idea how the print after foo ends up printing -10 while the
final one prints 10. But I don't see where this behavior is not just
as bad as changing functions at runtime with respect to looking at
code and understanding it and debugging errors.

Pascal J. Bourguignon

unread,
Apr 21, 2011, 4:41:21 AM4/21/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> On Apr 20, 6:33 pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:
>> TheFlyingDutchman <zzbba...@aol.com> writes:
>> > The compiler certainly recognizes "myvar" as being the local reference
>> > if I do
>>
>> > (defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20
>>
>> > How was the compiler able to recognize myvar as being the local one
>> > when there were two to choose from?
>>
>> Actually it doesn't.  It uses the special variables, as the earlier
>> example I gave showed.  It is just that LET interacts with special
>> variables bindings by binding and restoring the value.after exiting the
>> let block.
>
> So if have
> (let ( (a 10) ...
>
> and there is no global a, let makes a global symbol a, and assigns to
> it's variable cell, and then after it is done it nulls out the
> variable cell?

No. Everything you write here is wrong:

LET doesn't make symbols, it's the lisp reader that makes symbols.
LET doesn't touch the symbol value cell.
There is no such thing as a "variable cell".


>> You can generate even more amazing examples:
>>
>> (defvar *a* 10)
>> (defun foo () (setq *a* -10))
>> (print *a*) ; 1
>> (let ((*a* 20))
>>   (print *a*) ; 2
>>   (foo)
>>   (print *a*)) ; 3
>> (print *a*) ; 4
>>
> I have no idea how the print after foo ends up printing -10 while the
> final one prints 10.

That's because *A* has been declared SPECIAL.


> But I don't see where this behavior is not just as bad as changing
> functions at runtime with respect to looking at code and understanding
> it and debugging errors.

It is as bad, that's why SPECIAL variables are not normal variables, and
why you should use *STARS* to surround the name of the SPECIAL
variables, so that they stand out and everybody treat them very
SPECIALly and carefully.

Duane Rettig

unread,
Apr 21, 2011, 11:54:06 AM4/21/11
to
On Apr 20, 9:50 am, RG <rNOSPA...@flownet.com> wrote:
> In article
> <aae8102c-6b68-416b-a02d-aa8deb265...@18g2000prd.googlegroups.com>,

I saw it less as a criticism and more as the hazing of a newbie who
hasn't learned the language yet. There are other such "confusions" in
Common Lisp (or are they really?); for example, out of the three
defining forms DEFVAR, DEFPARAMETER, and DEFCONSTANT, why can you
store into the symbols defined by only two out of the three of these?
In fact, the answer is of the same kind as the above discussion, but
this example might not be as confusing to a newbie who has other
programming experience, because it might be obvious that a language
can take advantage of a constant (i.e. in this case, a value that
cannot be legally changed) and compile much more efficient code,
whereas it might not be quite as obvious in a language that mixes code
and data that some efficiency is gained in re-introducing that
separation of code and data.

Sometimes people on this newsgroup go overboard in hazing the newbies,
and sometimes that chases them off and other times that forces them to
drop their preconceived notions about what they think should be. But
the onus is always on a newbie to learn the language he is learning,
no matter what language it is. And Common Lisp happens to have a lot
of depth, so there is a lot of subtlety to learn. Sometimes a newbies
doesn't even know he's a newbie, until he realizes that he doesn't
understand why some particular design decision was made. And then he
usually has one of two reactions: he realizes that there is more to
the language than he thought, or he concludes for himself that the
language is a stupid language. Sadly, more and more people take the
second route, no matter what the language, and that is why we have
needless language wars.

Duane

Thomas A. Russ

unread,
Apr 21, 2011, 12:14:18 PM4/21/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> > (defvar *x* 'global)
>
> How is this is represented internally. Are there now two entries in a
> symbol table (or similar structure) for "*x*" and "global"? Does the
> entry for "*x*" point to a 5 cell structure known as a symbol and
> likewise for the "global" entry. Does the "symbol value cell" of the
> *x* symbol structure point to the symbol structure for the "global"
> symbol?

How this is represented internally is not specified. That is an
implementation detail left up to the discretion of the implementation.
All that the specification itself requires is that a symbol object be
able to return the appropriate values for SYMBOL-NAME, SYMBOL-PACKAGE,
SYMBOL-VALUE, SYMBOL-FUNCTION, etc.

These do not have to be implemented as slots. It would be perfectly
conforming for an implementation to create a symbol object with no slots
whatsoever and implement everything with, for example, hash tables. Or
an implementation could take a hybrid approach and have some slots and
some tables. This could be done as a means, say, of reducing the memory
footprint of symbols if it was determined that most symbols do not have
values or functions associated with them.

The specification generally mandates behavior and not particular memory
layouts or other implementation details. For example, it is required
that TYPE-OF applied to any object be able to return its type, but there
isn't any particular way that needs to be implemented. So, for example,
the actual implementation of a FIXNUM is not specified, only the way it
behaves.

Thomas A. Russ

unread,
Apr 21, 2011, 12:21:39 PM4/21/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> On Apr 20, 6:27滋pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:
> > TheFlyingDutchman <zzbba...@aol.com> writes:
> > > Can't any symbol be "shadowed lexically"?
> >
> > > (defvar a 10)
> > > (let ((a 20)) (print a)) => 20
> >
> > But not if you make it globally special:
> >
> > (defun foo () (setq a -10))
> > (let ((a 20)) (foo) (print a))
>
> It prints 20.

You obviously didn't try executing this in a Common Lisp implementation.

Or at least not in conjuction with the (defvar a) from above. It was
meant to be a continuation of the above code. [Without the DEFVAR form
first, the behavior is officially unspecified.]

(defvar a 10)


(defun foo () (setq a -10))
(let ((a 20)) (foo) (print a))

Pascal J. Bourguignon

unread,
Apr 21, 2011, 2:33:13 PM4/21/11
to
t...@sevak.isi.edu (Thomas A. Russ) writes:

> TheFlyingDutchman <zzbb...@aol.com> writes:
>
>> > (defvar *x* 'global)
>>
>> How is this is represented internally. Are there now two entries in a
>> symbol table (or similar structure) for "*x*" and "global"? Does the
>> entry for "*x*" point to a 5 cell structure known as a symbol and
>> likewise for the "global" entry. Does the "symbol value cell" of the
>> *x* symbol structure point to the symbol structure for the "global"
>> symbol?
>
> How this is represented internally is not specified.

There isn't even an API to know if a symbol has been declared special.
But we can detect it:


(defun specialp (symbol)
"Detects whether the symbol has been declared special."
(eval `(flet ((f () ,symbol)) (let ((,symbol t)) (not (nth-value 1 (ignore-errors (f))))))))

(defvar a 1)

(values
(funcall (compile nil (lambda ()
(let ((b 1))
(declare (special b))
(list (specialp 'a) (specialp 'b) (specialp 'c))))))
(list (specialp 'a) (specialp 'b) (specialp 'c)))

--> (T T NIL)
(T NIL NIL)

SPECIAL-ness is a dynamic property, in the global environment.

Tim Bradshaw

unread,
Apr 21, 2011, 3:29:33 PM4/21/11
to
On 2011-04-20 17:50:52 +0100, RG said:

> I'm not making any judgement on whether this design decision was good or
> bad. My only point is that it's unfair to criticize someone for being
> confused by the fact that three of the four combinations of
> lexical/dynamic and value/function are assignable and one is not.

I was thinking about this while out walking. Like you I don't have any
real axe to grind one way or the other (the difference being that I
hadn't even noticed that you couldn't do this, or rather it had never
occured to me that it was something I might want to do).

It does seem to me that the only time *I* use redefinition of functions
is while writing programs: I don't generally have code that calls
(setf symbol-function) at runtime, and where I do that code is support
for writing programs. if I have programs that want to call a function
which only be known at runtime they do that by variables and
funcall/apply. In fact if I wanted a function which might vary at
runtime as part of the normal running of the program I'd do something
like:

(defun default-foo (...) ...)

(defvar *foo* #'default-foo)

(defun foo (...)
(funcall *foo* ...))

For local functions you never need the redefinition-for-development
thing because you just redefine the function to which they are local.
So I would not find the ability to change the local function binding
useful (which is not to say it might not be useful at all).

If it was in the language, I think one thing would be that there would
need to be a mass of caveats. For instance the assumptions that can be
made about function definitions when compining a file should be able to
be made at least as strongly when compiling code that is in the scope
of a local function definition, so you would certainly need lots of
notinline declarations I think.

Now I've realised you can't do it I'm kind of annoyed though :-)

Tim Bradshaw

unread,
Apr 21, 2011, 3:53:22 PM4/21/11
to
On 2011-04-20 20:31:36 +0100, TheFlyingDutchman said:

> I don't think that seeing more easily what function is being referred
> to should be a rationale for using flet/labels. If a function has
> capability for general usage it should be global - so that it can
> receive general usage and reuse. If it can't be made global due to a
> lack of time to generalize it or an inherent specificity
> characteristic, then it should be local to avoid polluting the global
> arena with something that only has local usefulness.

There are lots of other reasons why a function might need to be local:
the most common being that it needs access to bindings which are also
local.

>
> The fact that Common Lisp allows the rebinding of global functions
> seems to cancel out the argument that Common Lisp shouldn't allow
> rebinding local functions because it is confusing, unless it is
> accompanied by an argument that Common Lisp shouldn't allow rebinding
> global functions as well. On the basis that rebinding a global
> function doesn't seem any less confusing than rebinding a local one.

I'm actually tempted to argue for that view (that all function
redefinition should be forbidden). The problem with it is that it
makes a tradtional Lisp programming practices impossible. In fact the
current situation, where redefinition of global functions is allowed,
but there is no support for redefining local functions is just
sufficient to support normal Lisp development style, while going no
further: that actually might be an argument for that being the right
compromise I suppose (as I said earlier I have no axe to grind about
this either way).

Tim Bradshaw

unread,
Apr 21, 2011, 4:02:45 PM4/21/11
to
On 2011-04-21 00:39:58 +0100, TheFlyingDutchman said:

> Can't anything that could be done with flet local function
> redefinition be done now with let and funcall. Is using let and
> funcall abuse?

Yes, it can, and no it isn't, in my opinion, if you need to do it (for
instance when you want to pass a function as a variable). You kind of
want letrec however. If you don't know Scheme, what letrec does is
establish bindings such that the binding is in scope in the value
expression. That sounds obscure, but consider something like this:

(defun bog (n)
(let ((foo (lambda (x)
(if (zerop x)
x
(funcall foo (1- x))))))
(funcall foo n)))

That doesn't work, because the binding of foo is not in scope in the
value expression.

CL has a version of letrec for function binings - labels - but not for
variable bindings. You can write letrec quite easily, or you can pass
the function to call in:

(defun bog (n)
(let ((foo (lambda (c x)
(if (zerop x)
x
(funcall c c (1- x))))))
(funcall foo foo n)))


Tim Bradshaw

unread,
Apr 21, 2011, 4:15:47 PM4/21/11
to
On 2011-04-21 07:14:55 +0100, TheFlyingDutchman said:

> Couldn't there be multiple settings via (defun..)? Other languages
> have REPLs but I don't think they have the equivalent of (setf (symbol-
> function...).

But that's largely because other languages are less open than Lisp.
Lisp tends to take the approach of providing a small number of magic
things and then implementing the rest as macros on top of them.

A concrete example of why that might be useful is: imagine you're
writing an object system for Lisp. You're going to want some kind of
generic function notion so you can say

(define-generic foo (...)
...)

Well, that macro wants to install a function definition, but it
probably doesn't want to use defun. So instead it can expand to
something which eventually does (setf (fdefinition ...) ...) to install
the definition.

And that's exactly what did happen when CLOS appeared for CL, for
instance, in the form of PCL.

Tim Bradshaw

unread,
Apr 21, 2011, 4:35:42 PM4/21/11
to
On 2011-04-21 01:03:42 +0100, TheFlyingDutchman said:

> How is this is represented internally. Are there now two entries in a
> symbol table (or similar structure) for "*x*" and "global"? Does the
> entry for "*x*" point to a 5 cell structure known as a symbol and
> likewise for the "global" entry. Does the "symbol value cell" of the
> *x* symbol structure point to the symbol structure for the "global"
> symbol?

Well, the point I was trying to make (badly) was mostly two things: the
way it's actually *implemented* is, well, implementation dependent, and
that (more importantly) the naive approaches tend not to work very well
when pushed too far: in particular the approach where the symbol *x*
has a slot of some kind which contains its current value (which is
called "shallow binding" historically) does not work at all well in the
case of really concurrent execution, because there's only one *x* and
yet you need different values in different threads of execution.

I think you're running into the problem that no-one is actually sitting
down and trying to write a coherent explanation of what the various
issues are, but rather responding to you by saying "no, you're wrong,
look at this which would not work ..." (I'm certainly guilty of this).
I don't think that's malice, it's just that writing a coherent
explanation is a lot of work. I wish I could say there were books you
could refer to, but I'm not sure there are - there are good bookx, for
sure, but I haven't read one which has a good, concise explanation of
this stuff, especially one including enough history that it makes
sense. If I have time I might try and write such an explanation (but
there are other people who know much more about it, both in terms of
history and implementation than me).

TheFlyingDutchman

unread,
Apr 21, 2011, 5:03:30 PM4/21/11
to
On Apr 21, 9:14 am, t...@sevak.isi.edu (Thomas A. Russ) wrote:

OK, in the future I will say "object with five attributes" for symbol.
But the issue remains, which is trying to visualize what is happening
under the covers with respect to global and local "variables" - and
that is with respect to location and contents - and not exact physical
representation.

You said:
"Actually it doesn't. It uses the special variables, as the earlier
example I gave showed. It is just that LET interacts with special
variables bindings by binding and restoring the value.after exiting
the
let block. "

It would seem that a let modifying a global variable temporarily in
order to provide a lexical variable is an implementation detail. Does
the specification require what you said, and if so, is there a reason
for that?

Thomas A. Russ

unread,
Apr 21, 2011, 6:42:53 PM4/21/11
to

A global variable, or more precisely a special variable is treated
specially by LET. In particular, LET does not change a special variable
into a lexical variable. It leaves it as a special variable, but
affects the value.

LET introduces variables which will either be lexical or special.
Absent any other declarations, the variables introduced by LET will be
lexical variables. But if there is a special declaration for that
symbol, either globally or with a more limited scope, then the variable
will be special.

Thomas A. Russ

unread,
Apr 21, 2011, 6:55:50 PM4/21/11
to
Tim Bradshaw <t...@tfeb.org> writes:

> On 2011-04-21 00:39:58 +0100, TheFlyingDutchman said:
>
> > Can't anything that could be done with flet local function
> > redefinition be done now with let and funcall. Is using let and
> > funcall abuse?
>
> Yes, it can, and no it isn't, in my opinion, if you need to do it (for
> instance when you want to pass a function as a variable). You kind of
> want letrec however. If you don't know Scheme, what letrec does is
> establish bindings such that the binding is in scope in the value
> expression. That sounds obscure, but consider something like this:
>
> (defun bog (n)
> (let ((foo (lambda (x)
> (if (zerop x)
> x
> (funcall foo (1- x))))))
> (funcall foo n)))
>
> That doesn't work, because the binding of foo is not in scope in the
> value expression.

Correct. You need to establish the scope before you assign the value.
The following will work:

(defun bog (n)
(let (foo)
(setq foo (lambda (x)


(if (zerop x)
x
(funcall foo (1- x)))))

(funcall foo n)))

although it does have the disadvantage of separating the value from
variable. Of course, one could fix this with some macrology, though.
Something along the lines of

(defmacro letrec (bindings &body body)
`(let ,(loop for b in bindings
when (consp b)
collect (first b)
else collect b)
,@(loop for b in bindings
when (consp b)
collect (cons 'setq b))
,@body))

(defun bog (n)
(letrec ((foo (lambda (x)


(if (zerop x)
x
(funcall foo (1- x))))))
(funcall foo n)))

TheFlyingDutchman

unread,
Apr 22, 2011, 1:21:18 AM4/22/11
to
>
> > It would seem that a let modifying a global variable temporarily in
> > order to provide a lexical variable is an implementation detail. Does
> > the specification require what you said, and if so, is there a reason
> > for that?
>
> A global variable, or more precisely a special variable is treated
> specially by LET.  In particular, LET does not change a special variable
> into a lexical variable.  It leaves it as a special variable, but
> affects the value.

This is a very confusing part of Common Lisp. Nothing about the name
"defvar" implies you are creating a "special variable" rather than a
global variable. And "special variable" is an unfortunate term,
particulary in light of the fact that it's glossary definition in the
CLHS is:

"special variable n. Trad. a dynamic variable."

So the glossary implies that dynamic variable is a better term than
special variable, and I bet anyone who hasn't been using Common Lisp
for years would agree.

The ISLisp creators really did it right by having defglobal and
(defdynamic, dynamic, dynamic-let, set-dynamic).


>
> LET introduces variables which will either be lexical or special.
> Absent any other declarations, the variables introduced by LET will be
> lexical variables.  But if there is a special declaration for that
> symbol, either globally or with a more limited scope, then the variable
> will be special.

Thanks, I see that now. Would much prefer let was always lexical.

TheFlyingDutchman

unread,
Apr 22, 2011, 1:31:12 AM4/22/11
to

No, that would be "prefer" to use format to print to the screen. Now
stand up, close your eyes, and spend a few minutes taking deep breaths
before going back to your one-handed perusal of comp.lang.lisp posts
from the 1990's.

TheFlyingDutchman

unread,
Apr 22, 2011, 1:49:19 AM4/22/11
to
On Apr 20, 5:36 pm, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:

Which statement or statements demonstrates a symbol's value being tied
to a variable (this was the question asked)?


>
> > Can't any symbol be "shadowed lexically"?
>
> If you start using loosy terminology, then 2=0.

It's not my terminology. And I am the one who added quotes to it.


>
> > (defvar a 10)
>
> > (let ( (a 20) ) (print a)) => 20
>
> That's not the point. The point is that:
>
> (defvar a 10)
>
> (defun f ()
> (print a))
>
> (let ((a 20))
> (f))
>
> ;; prints:
> 20
> ;; --> 20

Yes, even more unfortunate than "local dynamic scope" is "local scope
unless we declare a var which already has dynamic scope - scope".

>
> Or:
>
> (defun g ()
> (declare (special b))
> (print a))
>
> (let ((b 20))
> (declare (special b))
> (g))
>
> ;; prints:
> 20
> ;; --> 20
>
> > According to Ankur, (let ( (my-var 10) ) ), my-var is a symbol. Why
> > shouldn't I expect symbol-value to work on a symbol?
>
> Because symbols may be unbound (have no value), and in this case,
> symbol-value must signal an error.
>
> CL-USER> (ignore-errors (let ((my-var 10)) (symbol-value 'my-var)))
> NIL
> #<SYSTEM::SIMPLE-UNBOUND-VARIABLE #x000334342AE0>

Would you mind diagraming what is in memory from (let ((my-var 10)) )?


>
> >> What is variable is defined in section "3.1.2.1.1 Symbols as Forms":http://clhs.lisp.se/Body/03_abaa.htm
> >> ---
> >> If a form is a symbol, then it is either a symbol macro or a variable.
> >> ---
>
> >> In form (symbol-value 'foo) there is no reference to variable foo, (QUOTE
> >> FOO) is symbol itself, not variable denoted by it.
>
> >> So compiler just does not recognize it as variable access and thus it won't
> >> generate code which would access that variable.
>
> > Are you using "variable" synonomously with "symbol value"?
>
> No, he is not. Try to understand!

I asked a question. Try to read!

>
> >> In theory you could write a compiler which would recognize (symbol-value
> >> 'foo) as a variable access, but then it would be incompatible with CL.
>
> > Why do you say that (symbol-value 'foo) is doing in Common Lisp?
>
> He isn't saying that "(symbol-value 'foo) is doing in Common Lisp"
> because that sentence is meaningless in English.

"Why" should have been "what".

>
> Why do you ask meaningless and ungrammatical questions?

As if it was that hard to deduce the question.

>
> > The compiler certainly recognizes "myvar" as being the local reference
> > if I do
>
> > (defvar myvar 10) (let ( ( myvar 20) ) (print myvar)) => 20
>
> > How was the compiler able to recognize myvar as being the local one
> > when there were two to choose from?
>
> The fact that there is a local dynamic binding is irrelevant to the way
> dynamic binding works.
>
> Once you've used defvar, the symbol is declared special, and all the
> bindings occuring to this symbol are dynamic bindings. There's a single
> dynamic binding valid at any TIME. It doesn't depend on WHERE it is,
> local or global.

What an unfortunate name choice - defvar - when it should have been
defdynamic.

But the Europeans did get it right in ISLisp.

>
> Don't you know the difference between time and space?
>
> dynamic <-> time
> lexical <-> space
>
> "Local" is a space criteria. Try "present" for time.

I think I have it. Dynamic negatively impacts TIME of debug, while
lexical positively impacts SPACE required to store "Common Lisp
variable scope discussion" on Google's servers.

>
> >> It IS NOT a symbol. Its NAME is a symbol.
>
> >> Is it that hard to recognize difference between NAME of a thing and thing
> >> ITSELF?
>
> > I think we agree a symbol is a structure with five slots. One points
> > to something called the "symbol value". One points to something called
> > the "symbol name". Is that what you are referring to when you talk
> > about "thing itself" and "name"?
>
> No. He was asking the question in general. But you could apply it in
> particular, and in this case, the "thing itself" refers to the variable,
> which is not its name, the symbol.
>
> Can't you understand that symbols are not variables, but the names of
> the variables?

No, I cannot undertand that. A symbol is "an object with 5
attributes". That's the one thing I know for sure as it is in the
beloved CLHS. However, I haven't a clue as to how that relates to a
variable name.

>
> > Do you disagree with the statement that what is defined with a let is
> > a symbol and what is defined with flet is a symbol?
>
> Yes, we do disagree.

Well then you should have responded to Ankur when he stated it - along
with something about lexical scoping.

>
> Try to read the description of LET in CLHS, and tell us if you see the
> word "symbol".

Try to read this thread and tell us if you see me coming up with the
idea that let defines symbols.


>
> >> You have a wrong impression that everything works through symbols in CL. It
> >> is just wrong. Symbols are used at time of compilation, and sometimes in
> >> runtime.
>
> > I asked what was defined by flet and let. I was told there were
> > symbols.
>
> This is wrong. LET defines variables, FLET defines functions.

Can you describe what occurs in memory after the execution of let and
flet which create one variable, and one function respectively?

>
> > It's not hard to get the idea that everything works through
> > symbols if everything is a symbol.
>
> That's why you should read the CLHS first.

Someone asked a few months ago if "Lisp is good for a starter?". Most
people remained silent. You were one of the few who said yes. Is that
your recommendation to that person - open up your browser and read an
ANSI Specification to learn Common Lisp?

>
> > I found this statement (http://clhs.lisp.se/Body/t_symbol.htm#symbol


> > ):
>
> > "Symbols are used as identifiers for lexical variables and lexical
> > function definitions, but in that role, only their object identity is
> > significant. Common Lisp provides no operation on a symbol that can
> > have any effect on a lexical variable or on a lexical function
> > definition."
>
> > This statement follows a blurb about how a symbol has 5 cells. It
> > would be nice if the person who wrote the above statement had seen fit
> > to explain how the phrase "only their object identity is significant"
> > relates to a structure of five cells which are used to hold the
> > address of 5 different objects and for which there are multiple
> > functions to deal with what is referred to by those 5 cells.
>
> But since identity doesn't relate to structure, what do you want us to
> explain?

The phrase "only their object identity is significant". That is a
phrase that is only understood by the person writing it, or by someone
who already knew what the person was trying to refer to before they
read the statement.

>
> How can we explain something that doesn't exist?

Symbols exist, and are objects with 5 attributes. Variables exist and
take up memory locations. Despite the fact that it hasn't been done,
it is certainly possible to explain the relationship between them -
assuming there is one.

>
> What can I tell you about the odd multiples of two? That they are blue?
> That they can beat you in the face? That they can go faster than light?
> How are you smarter knowing all these facts about an entity that doesn't
> exist?

Which entity doesn't exist?

>
> My advice would be for you to learn some basic logic...

I think a basic understanding of cryptography would be better
indicated in this situation.

TheFlyingDutchman

unread,
Apr 22, 2011, 2:44:20 AM4/22/11
to
On Apr 21, 1:41 am, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:
>

> >> Actually it doesn't. It uses the special variables, as the earlier
> >> example I gave showed. It is just that LET interacts with special
> >> variables bindings by binding and restoring the value.after exiting the
> >> let block.
>
> > So if have
> > (let ( (a 10) ...
>
> > and there is no global a, let makes a global symbol a, and assigns to
> > it's variable cell, and then after it is done it nulls out the
> > variable cell?
>
> No.  Everything you write here is wrong:
>
> LET doesn't make symbols, it's the lisp reader that makes symbols.

Fine, then let's modify it. "let causes the lisp reader to make a
global symbol a".

> LET doesn't touch the symbol value cell.

Then how does this occur:

"It uses the special variables, as the earlier example I gave showed.
It is just that LET interacts with special variables bindings by
binding and restoring the value.after exiting the
let block."

> There is no such thing as a "variable cell".

"variable cell" was used in place of "value attribute"

>
> >> You can generate even more amazing examples:
>
> >> (defvar *a* 10)
> >> (defun foo () (setq *a* -10))
> >> (print *a*)  ; 1
> >> (let ((*a* 20))
> >> (print *a*) ; 2
> >> (foo)
> >> (print *a*)) ; 3
> >> (print *a*) ; 4
>
> > I have no idea how the print after foo ends up printing -10 while the
> > final one prints 10.
>
> That's because *A* has been declared SPECIAL.

More correctly and clearly:
*A* has been established as a dynamic variable which causes let to
behave differently than God intended.

Ankur

unread,
Apr 22, 2011, 4:00:08 AM4/22/11
to
* TheFlyingDutchman <zzbb...@aol.com>

>> LET doesn't make symbols, it's the lisp reader that makes symbols.
>
> Fine, then let's modify it. "let causes the lisp reader to make a
> global symbol a".

LET does not cause the reader to make symbols. The reader makes
a symbol when it reads a symbol. There is no such thing as a global symbol.

>> LET doesn't touch the symbol value cell.

Except for special variables. But this is a special case.

> More correctly and clearly:
> *A* has been established as a dynamic variable which causes let to
> behave differently than God intended.

It helps to understand something before you critize it. You are asking
how LET works, yet are so sure that its behaviour is wrong before you
comprehend the answers you are given. Amazing.

--
Ankur

Ankur

unread,
Apr 22, 2011, 4:00:47 AM4/22/11
to
* TheFlyingDutchman <zzbb...@aol.com>

>> Notice variables are not first class objects, only symbols and values.
>> So we cannot print a variable, only the name of a variable (which is a
>> symbol), or the value of a variable.
>
> Which statement or statements demonstrates a symbol's value being tied
> to a variable (this was the question asked)?

Your conception is wrong. As people have tried to explain to you, a
symbol's value is not the same as the value of a variable.

The examples in the spec for SYMBOL-VALUE should have clued you in to this.

> Yes, even more unfortunate than "local dynamic scope" is "local scope
> unless we declare a var which already has dynamic scope - scope".

Since you don't understand variable binding, it may be wise to reserve
judgement on these matters.

>> > Are you using "variable" synonomously with "symbol value"?
>>
>> No, he is not. Try to understand!
>
> I asked a question. Try to read!

You received an answer that is the crucial point you seem to have
been missing. YOU read.

>> Don't you know the difference between time and space?
>>
>> dynamic <-> time
>> lexical <-> space
>>
>> "Local" is a space criteria. Try "present" for time.
>
> I think I have it. Dynamic negatively impacts TIME of debug, while
> lexical positively impacts SPACE required to store "Common Lisp
> variable scope discussion" on Google's servers.

Your flippancy indicates that you are missing the point. Again.

>> > Do you disagree with the statement that what is defined with a let is
>> > a symbol and what is defined with flet is a symbol?
>>
>> Yes, we do disagree.
>
> Well then you should have responded to Ankur when he stated it - along
> with something about lexical scoping.

I did not state that LET defines symbols; that is your own
misconception.

In (LET ((ABC 1)) ), ABC is a symbol. A symbol is not, however, being
defined by LET, which creates bindings.

The variable is being bound to 1. This is distinct from
setting the SYMBOL-VALUE.

> A symbol is "an object with 5 attributes". That's the one thing I
> know for sure

And that is a big hindrance to your understanding. Please forget it as
it has nothing to do with lexical variables, which would exist even if
symbols had no slots; only their object identity is significant.

>> Try to read the description of LET in CLHS, and tell us if you see the
>> word "symbol".
>
> Try to read this thread and tell us if you see me coming up with the
> idea that let defines symbols.

You have been repeating your mantra about symbols having 5 slots.

>> > I asked what was defined by flet and let. I was told there were
>> > symbols.

NO. You were told: "You are creating lexical bindings (unless
local_var is declared special)."

> open up your browser and read an ANSI Specification to learn Common Lisp?

Yes. This is probably the best way to learn the language.

> Symbols exist, and are objects with 5 attributes. Variables exist and
> take up memory locations.

Variables don't take up memory locations. Please forget that you are
running hardware as it is a detriment to your understanding.

> Despite the fact that it hasn't been done,
> it is certainly possible to explain the relationship between them -
> assuming there is one.

*only their object identity is significant*

It might be helpful to learn some basics of the lambda calculus.

--
Ankur

TheFlyingDutchman

unread,
Apr 22, 2011, 4:39:14 AM4/22/11
to
On Apr 22, 1:00 am, Ankur <an...@lipidity.com> wrote:
> * TheFlyingDutchman <zzbba...@aol.com>

>
> >> LET doesn't make symbols, it's the lisp reader that makes symbols.
>
> > Fine, then let's modify it. "let causes the lisp reader to make a
> > global symbol a".
>
> LET does not cause the reader to make symbols. The reader makes
> a symbol when it reads a symbol. There is no such thing as a global symbol.

Fine, then let's modify it. Some of the textual data inside a let form
causes the reader to make a symbol.

>
> >> LET doesn't touch the symbol value cell.
>
> Except for special variables. But this is a special case.

I think dynamic variable is a better term than special variable. And
the Common Lisp Hyperspec seems to agree:

special variable n. Trad. a dynamic variable.

>


> > More correctly and clearly:
> > *A* has been established as a dynamic variable which causes let to
> > behave differently than God intended.
>
> It helps to understand something before you critize it. You are asking
> how LET works, yet are so sure that its behaviour is wrong before you
> comprehend the answers you are given. Amazing.

Let's take a look at how (let) works:

(defvar a 10)


(defun foo () (setq a -10))

(let ((a 20)) (foo) (print a) ) => -10


And you defend that behavior? Amazing.

Piotr Chamera

unread,
Apr 22, 2011, 4:51:51 AM4/22/11
to
W dniu 2011-04-21 08:28, TheFlyingDutchman pisze:

> So if have
> (let ( (a 10) ...
>
> and there is no global a, let makes a global symbol a, and assigns to
> it's variable cell, and then after it is done it nulls out the
> variable cell?

I'am also a newbie in Lisp, so mybe I'm wrong but i think that
this situation is direct analog of that in eg C compilation.

Lisp reader reads 'a' as symbol and treats it as identifier of something
(in this example number 10 - 'object') through compilation prosess, then
identifier is dropped – in created object code there is only 'object'
(be it in register, place in memory, direct constant in processor
instruction or something else) without any identitfier (except debug
information).

If 'a' is special, then it is totally different...

TheFlyingDutchman

unread,
Apr 22, 2011, 4:59:48 AM4/22/11
to
On Apr 22, 1:00 am, Ankur <an...@lipidity.com> wrote:
> * TheFlyingDutchman <zzbba...@aol.com>
>
> >> Notice variables are not first class objects, only symbols and values.
> >> So we cannot print a variable, only the name of a variable (which is a
> >> symbol), or the value of a variable.
>
> > Which statement or statements demonstrates a symbol's value being tied
> > to a variable (this was the question asked)?
>
> Your conception is wrong. As people have tried to explain to you, a
> symbol's value is not the same as the value of a variable.

I didn't say a "symbol's value was the same as the value of a
variable." And I was asking about someone else's statement: "But


symbol's value becomes tied to variable with corresponding name only

when variable is declared special." was

>
> The examples in the spec for SYMBOL-VALUE should have clued you in to this.
>
> > Yes, even more unfortunate than "local dynamic scope" is "local scope
> > unless we declare a var which already has dynamic scope - scope".
>
> Since you don't understand variable binding, it may be wise to reserve
> judgement on these matters.

Variable binding? Heck, I don't even understand the concept of
variables - in Common Lisp - at this point.

>
> >> > Are you using "variable" synonomously with "symbol value"?
>
> >> No, he is not.   Try to understand!
>
> > I asked a question. Try to read!
>
> You received an answer that is the crucial point you seem to have
> been missing. YOU read.

No, the crucial point is that I asked a question. Therefore, I was
"trying to understand".

>
> >> Don't you know the difference between time and space?
>
> >> dynamic <-> time
> >> lexical <-> space
>
> >> "Local" is a space criteria.  Try "present" for time.
>
> > I think I have it. Dynamic negatively impacts TIME of debug, while
> > lexical positively impacts SPACE required to store "Common Lisp
> > variable scope discussion" on Google's servers.
>
> Your flippancy indicates that you are missing the point. Again.

The point is that there is nothing flip about this unfortunate
behavior:

(defvar a 10)
(defun foo () (setq a -10))
(let ((a 20)) (foo) (print a)) => -10

>


> >> > Do you disagree with the statement that what is defined with a let is
> >> > a symbol and what is defined with flet is a symbol?
>
> >> Yes, we do disagree.
>
> > Well then you should have responded to Ankur when he stated it - along
> > with something about lexical scoping.
>
> I did not state that LET defines symbols; that is your own
> misconception.

I asked what a was called in (let ((a ... and you said:

"They are symbols. You are creating lexical bindings (unless
local_var
is declared special)."

> In (LET ((ABC 1)) ), ABC is a symbol. A symbol is not, however, being


> defined by LET, which creates bindings.
>
> The variable is being bound to 1. This is distinct from
> setting the SYMBOL-VALUE.

(let ((abc 1)) )

Where is the variable?

>
> > A symbol is "an object with 5 attributes". That's the one thing I
> > know for sure
>
> And that is a big hindrance to your understanding. Please forget it as
> it has nothing to do with lexical variables, which would exist even if
> symbols had no slots; only their object identity is significant.

Unfortunately I can't forget it because this discussion is riddled
with people other than me talking about symbols.

>
> >> Try to read the description of LET in CLHS, and tell us if you see the
> >> word "symbol".
>
> > Try to read this thread and tell us if you see me coming up with the
> > idea that let defines symbols.
>
> You have been repeating your mantra about symbols having 5 slots.

Mentioning that symbols have 5 slots (attributes) can be twisted into
"let defines symbols", but when I talked about abc in (let ((abc...
being a symbol, I was careful to mention that you said it was.

>
> >> > I asked what was defined by flet and let. I was told there were
> >> > symbols.
>
> NO. You were told: "You are creating lexical bindings (unless
> local_var is declared special)."

I was told:
"They are symbols. You are creating lexical bindings (unless
local_var
is declared special)."


>
> > open up your browser and read an ANSI Specification to learn Common Lisp?
>
> Yes. This is probably the best way to learn the language.
>
> > Symbols exist, and are objects with 5 attributes. Variables exist and
> > take up memory locations.
>
> Variables don't take up memory locations. Please forget that you are
> running hardware as it is a detriment to your understanding.

What is your definition of a variable?

>
> > Despite the fact that it hasn't been done,
> > it is certainly possible to explain the relationship between them -
> > assuming there is one.
>
> *only their object identity is significant*
>
> It might be helpful to learn some basics of the lambda calculus.

I would think studying the source code to a Common Lisp implementation
would give me the answer faster than learning the basics of lambda
calculus, or asking questions in this thread.

TheFlyingDutchman

unread,
Apr 22, 2011, 5:10:02 AM4/22/11
to
On Apr 22, 1:51 am, Piotr Chamera <piotr_cham...@poczta.onet.pl>
wrote:

Could be. It seems like someone was saying something like that. But
wouldn't the direct analogy be that Common Lisp creates an entry - in
the table that it uses to search for symbols - for the variable? Just
as C creates an entry in a symbol table for it's variables?

Teemu Likonen

unread,
Apr 22, 2011, 5:25:07 AM4/22/11
to
* 2011-04-22T01:59:48-07:00 * TheFlyingDutchman wrote:

> The point is that there is nothing flip about this unfortunate
> behavior:
>
> (defvar a 10)
> (defun foo () (setq a -10))
> (let ((a 20)) (foo) (print a)) => -10

What do you think is wrong there? That's how dynamic (special) variables
work. Here's an example in a language which only have dynamic variables:


#!/bin/sh

a=10
foo () { a=-10; }

program () {
local a=20
foo
echo "Local binding: $a"
}

program
echo "Global binding: $a"


It will echo

Local binding: -10
Global binding: 10

Ankur

unread,
Apr 22, 2011, 5:35:50 AM4/22/11
to
* TheFlyingDutchman <zzbb...@aol.com>

> Fine, then let's modify it. Some of the textual data inside a let form
> causes the reader to make a symbol.

This has nothing to do with LET. "Any token that is not a potential
number, does not contain a package marker, and does not consist
entirely of dots will always be interpreted as a symbol."

> Let's take a look at how (let) works:
>
> (defvar a 10)
> (defun foo () (setq a -10))
> (let ((a 20)) (foo) (print a) ) => -10
>
> And you defend that behavior? Amazing.

I haven't yet defended any behaviour of LET; rather I've pointed out
concepts that you haven't grasped.

But speaking of special variables, I don't defend the behaviour of
LET. I praise it. Loudly. It is magnificent.

--
Ankur

Ankur

unread,
Apr 22, 2011, 5:53:31 AM4/22/11
to
* TheFlyingDutchman <zzbb...@aol.com>

> I asked what a was called in (let ((a ... and you said:
>
> "They are symbols. You are creating lexical bindings (unless
> local_var is declared special)."

Correct.

> (let ((abc 1)) )
>
> Where is the variable?

"If a form is a symbol, then it is either a symbol macro or a variable."

"If a form is a symbol that is not a symbol macro, then it is the name
of a variable, and the value of that variable is returned."

See CLHS 3.1.2.1.1 Symbols as Forms

In (let ((ABC 10)) (print ABC)), the symbol ABC is the name of a variable.

> Unfortunately I can't forget it because this discussion is riddled
> with people other than me talking about symbols.

It's the 5 slots thing which you should ignore, not symbols in general.

>> It might be helpful to learn some basics of the lambda calculus.
>
> I would think studying the source code to a Common Lisp implementation
> would give me the answer faster than learning the basics of lambda
> calculus, or asking questions in this thread.

I don't think studying the implementation will be very helpful.

--
Ankur

Stefan Nobis

unread,
Apr 22, 2011, 6:44:28 AM4/22/11
to
TheFlyingDutchman wrote:

> Variable binding? Heck, I don't even understand the concept of
> variables - in Common Lisp - at this point.

Maybe you should first try to understand some definition, before digging
deeper into special features of CL?

An important note: Most language descriptions and books tend to more or
less compeletly ignore at least parts of the compiler, like the
reader/lexer and parser, and describe thing more or less only from the
runtime perspective.

In CL this is quite different, because the compiler, including the
reader and the parser, is an important part of the language and (in most
cases) always available, even at runtime.

So in CL you have to differentiate between more layers than in most
other languages.

The handling and naming around identifiers, variables and symbols show
this problem. In most languages there are identifiers that for example
represent a variable. So for practical purposes it's OK to think of
identifier, variable name and the variable itself as the same thing.

Take a simple code snippet like this

(let ((x 10))
(princ x))

As defined by the CLHS the name or identifier x represents a variable
(also called a variable binding or just binding). When executing the
code, the variable x will be bound to the value 10. This is quite the
same as in most other languages.

On the other hand, CL has a bit more to say about this. When the
compiler or interpreter reads the source code, it reads the characters
and tries to make sensible data structures from the read source. So in
this example the parser creates the three symbols LET, X and PRINC (just
using capital letters in order to emphasize the different context and to
honour the Lisp tradition). Later on in the process of compilation and
execution, the symbol X is used to name/identify the variable x (but the
symbol is usually not present in the compiled machine code). Here is the
assembler code of the above source (produced by Clozure Common Lisp
compiler):

;;; (let ((x 10)) (princ x))
[15] (movl ($ 80) (% arg_z.l))
[20] (movl ($ 8) (% nargs))
[25] (movq (@ 'PRINC (% fn)) (% temp0))
[32] (leaveq)
[33] (jmpq (@ 10 (% temp0)))

As you see: No "x" in the instructions, just the literal value 10.

In the first place a variable is an abstract concept of the
compiler/interpreter, as are symbols. Symbols may be thought of another
layer, adding more flexibility and some new features, usually not found
in most other languages.

To summarize: In simple cases symbols are tokens of the parser to denote
variables and functions. But in CL they have quite a bit more features
(and therefore its important to make the distinction between variables
and symbols).

And for the naming (like special variable etc.): CL comes with a lengthy
history, so not each single decision is always perfect and has a clear
rationale. Try to embrace these differences as a chance for new insights.

> The point is that there is nothing flip about this unfortunate
> behavior:
>
> (defvar a 10) (defun foo () (setq a -10)) (let ((a 20)) (foo) (print
> a)) => -10

I would say this is not unfortunate but the only way to sanely deal with
global state. :)

Within a lexical scope I'm able to switch the global state. As soon as I
leave the said lexical scope, the original global state is restored.

On the other hand, if I don't want a lexically bound switch of the
global state, I just don't rebind the global special variable, as in

(defvar a 10)
(defun foo () (setq a -10))

(print a)
(foo)
(print a)

So I always have the choice.

> Mentioning that symbols have 5 slots (attributes) can be twisted
> into "let defines symbols", but when I talked about abc in (let
> ((abc... being a symbol, I was careful to mention that you said it
> was.

The important thing to remember here is that there are different layers
and views of the source. There are at least the viewpoint of the reader,
the parser, and the runtime. The symbols are created by the
reader/parser. What let semantically means is defined by the runtime. So
I would say: let establishes a variable binding and the name of the
variable (used during compilation or interpretation) is denoted by a
symbol (as each symbol in CL is unique, i.e. there are no two different
symbols with the same (fully qualified) name, it is OK to identify a
symbol with its (fully qualified) name). A symbol value is a special
thing and not all variables are stored in the value cell of the symbol
denoting the variable:

? (let ((x 10)) (boundp 'x))
;Compiler warnings :
; In an anonymous lambda form at position 0: Unused lexical variable X
NIL

Here you can see, that let really established only a (lexical) variable
binding, where the name of the variable is denoted by a symbol (or the
symbol name). The value cell of a symbol is usually only used for
special variables:

? (defvar *special* 10)
*SPECIAL*
? (boundp '*special*)
T

Therefore a variable and a symbol are quite different things, but they
have some connections.

--
Stefan.

WJ

unread,
Apr 22, 2011, 7:22:55 AM4/22/11
to
TheFlyingDutchman wrote:

>
> The point is that there is nothing flip about this unfortunate
> behavior:
>
> (defvar a 10)
> (defun foo () (setq a -10))
> (let ((a 20)) (foo) (print a)) => -10

You should be using Scheme.

gambit> (define a 8)
gambit> (define (foo) (set! a -9))
gambit> (let ((a 22)) (foo) (pp a))
22
gambit> (pp a)
-9

Jussi Piitulainen

unread,
Apr 22, 2011, 9:12:47 AM4/22/11
to
WJ writes:

> You should be using Scheme.

The Scheme counterpart for dynamic variables seems to be a parameter:

> (define a (make-parameter 8))
> (define (foo) (a))
> (list (foo) (parameterize ((a -9)) (foo)) (foo))
(8 -9 8)

I guess these got into R6RS, since they are in Ikarus, in which the
above was run. They are in the new draft of R7RS.

Parameters are made with (make-parameter init), and then dynamically
bound with (parameterize <bindings> <body>) for the duration of the
<body>. Parameters are immutable, and they do not interact with let in
any special way.

Pascal Costanza

unread,
Apr 22, 2011, 3:21:40 PM4/22/11
to
On 20/04/2011 14:01, Anticomuna wrote:
> On 20 abr, 06:10, "Captain Obvious"<udode...@users.sourceforge.net>
> wrote:
>> A> Common Lisp is not an end in itself. A programming language is only as
>> A> good as it is useful.
>>
>> It is useful enough for me.
>>
>> A> Changing things that don't make sense is a necessity. Stupid would be
>> A> to blindly follow some standard, with stupidities and all.
>>
>> I don't see how implementing this "feature" helps anybody.
>> Dynamic redefinition is not considered a good style. In more progressive
>> functional programming languages (e.g. Haskell) there is no even analog of
>> SETQ.
>> OTOH if local functions can be changed in runtime certain optimizations are
>> not possible.
>>
>> So this change will be a move from clean and fast Lisp to messy and slow
>> one. It is a change in a wrong direction.
>
> Someone who wants immutable state wouldn't be using a language like
> Lisp in the first place. So the more "progressive" argument is BS,
> especially because "progressive" is your opinion. I don't think it is
> progressive at all, it is the wrong direction.
>
> Besides, optimization is the implementor's business, not the user's.
> The user shouldn't be forced to work in a stupid way because of such
> details. Making people's life easier is what computers are about, and
> this is the same reason we have GUIs and graphical development
> environments there days instead of the command line and vi, even if it
> uses a lot more memory.

Just define your own variation of flet, and be done with it. No need to
waste time complaining about a missing feature that is trivial to add
yourself.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.

Thomas A. Russ

unread,
Apr 22, 2011, 8:27:01 PM4/22/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> I would think studying the source code to a Common Lisp implementation
> would give me the answer faster than learning the basics of lambda
> calculus, or asking questions in this thread.

http://sourceforge.net/projects/sbcl/files/sbcl/1.0.47/sbcl-1.0.47-source.tar.bz2/download

Thomas A. Russ

unread,
Apr 22, 2011, 8:22:16 PM4/22/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:
> On Apr 20, 5:36 pm, "Pascal J. Bourguignon" <p...@informatimago.com>
> wrote:

> > CL-USER> (ignore-errors (let ((my-var 10)) (symbol-value 'my-var)))
> > NIL
> > #<SYSTEM::SIMPLE-UNBOUND-VARIABLE #x000334342AE0>
>
> Would you mind diagraming what is in memory from (let ((my-var 10)) )?

What exists in memory happens to be implementation dependent. But in
many implementations on stock (or probably even specialized) hardware,
what you get in computer memory is a stack frame with the fixnum 10 in
it. The symbol for a lexical variable is used solely by the compiler to
manage a mapping to where the lexical binding is located. This is
typically some stack location, and once the compiler is done, there is
no need (save perhaps for debugging purposes) to keep the symbol around.

It isn't really any different in most other programming languages.
Lexical variable bindings are handled by stack frames.

> > Can't you understand that symbols are not variables, but the names of
> > the variables?
>
> No, I cannot undertand that. A symbol is "an object with 5
> attributes". That's the one thing I know for sure as it is in the
> beloved CLHS. However, I haven't a clue as to how that relates to a
> variable name.

Symbols are used in Common Lisp to name lots of things. Among them are
variables, types, functions and classes. You will note that some of
these uses of a symbol as a name don't correspond at all to the 5
attributes.

Symbols are just a handy object to use as a name. They are often used
as keys in hash tables or other structures. They can have property
lists associated with them.

...

> > That's why you should read the CLHS first.
>
> Someone asked a few months ago if "Lisp is good for a starter?". Most
> people remained silent. You were one of the few who said yes. Is that
> your recommendation to that person - open up your browser and read an
> ANSI Specification to learn Common Lisp?

No. You only need to read the specification if you want to engage in
detailed discussions of the semantics of Common Lisp. If you, instead,
would take the language and the way it works as presented in a tutorial,
then it will be easier.

I am reminded of a remark from Gerald Sussman, who observed that Scheme
was easier to teach to incoming freshman at MIT who had NOT had any
exposure to programming languages than it was to those who "knew" how to
program.

But if you want to discuss details of how the language works, you do
need to become familiar with the language specification.

Thomas A. Russ

unread,
Apr 22, 2011, 8:07:20 PM4/22/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> >
> > > It would seem that a let modifying a global variable temporarily in
> > > order to provide a lexical variable is an implementation detail. Does
> > > the specification require what you said, and if so, is there a reason
> > > for that?
> >
> > A global variable, or more precisely a special variable is treated

> > specially by LET. Ž In particular, LET does not change a special variable
> > into a lexical variable. Ž It leaves it as a special variable, but


> > affects the value.
>
> This is a very confusing part of Common Lisp. Nothing about the name
> "defvar" implies you are creating a "special variable" rather than a
> global variable.

Except for the first sentence in the description of DEFVAR in the
specification:

"defparameter and defvar establish name as a dynamic variable."

http://www.lispworks.com/documentation/HyperSpec/Body/m_defpar.htm#defvar

That clearly indicates that a dynamic variable is created.

> And "special variable" is an unfortunate term,
> particulary in light of the fact that it's glossary definition in the
> CLHS is:
>
> "special variable n. Trad. a dynamic variable."
>
> So the glossary implies that dynamic variable is a better term than
> special variable, and I bet anyone who hasn't been using Common Lisp
> for years would agree.

Quite possibly. On the other hand, the name of the declaration that you
use to create a "dynamic variable" is named "special". So at some point
you are forced to confront the use of both "dynamic" and "special" to
name the phenomenon.

> > LET introduces variables which will either be lexical or special.
> > Absent any other declarations, the variables introduced by LET will be

> > lexical variables. Ž But if there is a special declaration for that


> > symbol, either globally or with a more limited scope, then the variable
> > will be special.
>
> Thanks, I see that now. Would much prefer let was always lexical.

I suppose. It would necessitate introducing a new binding form for
speical variables, then. And it would make interleaving LET* type
bindings for lexical and special variables a bit more difficult.

But in practice this isn't really a problem, largely because just about
everyone follows the special/dynamic variable naming convention. So you
just don't end up with name conflicts between dynamic and lexical
variables. Since in practice this is a non-issue, you won't find much
interest in changing this.

Thomas A. Russ

unread,
Apr 22, 2011, 8:36:35 PM4/22/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

> On Apr 22, 1:00滋am, Ankur <an...@lipidity.com> wrote:
> > * TheFlyingDutchman <zzbba...@aol.com>
> >
> > >> LET doesn't make symbols, it's the lisp reader that makes symbols.
> >
> > > Fine, then let's modify it. "let causes the lisp reader to make a
> > > global symbol a".
> >
> > LET does not cause the reader to make symbols. The reader makes
> > a symbol when it reads a symbol. There is no such thing as a global symbol.
>
> Fine, then let's modify it. Some of the textual data inside a let form
> causes the reader to make a symbol.

Um, you still don't get this.

Until the reader is done, there is no "let form". The let form is a
consequence of the reader encountering a series of textual characters.
Do you think the the opening parenthesis causes the reader to make the
symbol LET?

No. The reader encounters a sequence of textual characters and returns
a lisp form. If the sequence of characters happen to match the syntax
of a symbol, then a symbol is returned or created if it doesn't already
exist.

Symbols therefore have to already exist before there is even a let form,
since the symbol LET has to have been recognized before the interpreter
or compiler can even know there is a LET form.

Tim X

unread,
Apr 22, 2011, 11:10:47 PM4/22/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

>
> Let's take a look at how (let) works:
>
> (defvar a 10)
> (defun foo () (setq a -10))
> (let ((a 20)) (foo) (print a) ) => -10
>
>
> And you defend that behavior? Amazing.
>

I thought I understood some of your 'issues', but now I'm confused? The
above example makes perfect sense to me. Which 'a' were you expecting to
be modified when you call foo within the scope of your let? I'm assuming
you had expected the special (dynamic in your terminology?) to be set to
-10 and for the lexical binding to remain at 20? If that was the
behavior you wanted, isn't that what declare special etc is for?

I must be missing something as the example seems fine to me and
perfectly defensible.

Tim

--
tcross (at) rapttech dot com dot au

RG

unread,
Apr 23, 2011, 2:13:15 AM4/23/11
to
In article <87aafhb...@rapttech.com.au>,
Tim X <ti...@nospam.dev.null> wrote:

Suppose I want to make a lexical closure. I type this:

(let ((v 0))
(lambda () (incf v)))

But that may or may not give me a lexical closure depending on whether
or not at some previous point in this current session someone has typed
(defvar v ...) or some such thing. This is why the *earmuffs*
convention was developed, but any time you have to have a rule like that
it's an indication of a poor design. If all special variables should
have earmuffs, why not build that into the language spec?

The answer is that DEFVAR works the way it does not because it's a good
design, but because part of CL's mission statement was to unify
dynamically and lexically scoped lisps. But no one uses dynamically
scoped Lisps any more, so we are saddled with a bad design that was put
in place to satisfy a requirement that no one cares about any more.

rg

Pascal J. Bourguignon

unread,
Apr 23, 2011, 2:17:14 AM4/23/11
to
RG <rNOS...@flownet.com> writes:

> Suppose I want to make a lexical closure. I type this:
>
> (let ((v 0))
> (lambda () (incf v)))
>
> But that may or may not give me a lexical closure depending on whether
> or not at some previous point in this current session someone has typed
> (defvar v ...) or some such thing. This is why the *earmuffs*
> convention was developed, but any time you have to have a rule like that
> it's an indication of a poor design. If all special variables should
> have earmuffs, why not build that into the language spec?
>
> The answer is that DEFVAR works the way it does not because it's a good
> design, but because part of CL's mission statement was to unify
> dynamically and lexically scoped lisps. But no one uses dynamically
> scoped Lisps any more,

emacs lisp.


> so we are saddled with a bad design that was put in place to satisfy
> a requirement that no one cares about any more.

Thanks to this design choice, you can easily run emacs lisp code on any
CL implementation. :-)


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

TheFlyingDutchman

unread,
Apr 23, 2011, 3:40:34 AM4/23/11
to
On Apr 22, 2:35 am, Ankur <an...@lipidity.com> wrote:
> * TheFlyingDutchman <zzbba...@aol.com>
>
> > Fine, then let's modify it. Some of the textual data inside a let form
> > causes the reader to make a symbol.
>
> This has nothing to do with LET. "Any token that is not a potential
> number, does not contain a package marker, and does not consist
> entirely of dots will always be interpreted as a symbol."

You do realize, that when I was asking about what the a in (flet ((a
and (let ((a was called, I was talking about what is created. Not
anything temporarily created by the "lisp reader". Your answer was
symbols. Do you want to stick with that answer?

>
> > Let's take a look at how (let) works:
>
> > (defvar a 10)
> > (defun foo () (setq a -10))
> > (let ((a 20)) (foo) (print a) ) => -10
>
> > And you defend that behavior? Amazing.
>
> I haven't yet defended any behaviour of LET; rather I've pointed out
> concepts that you haven't grasped.
>
> But speaking of special variables, I don't defend the behaviour of
> LET. I praise it. Loudly. It is magnificent.

I will leave it to those who chronicle our history as to whether you
are remembered as brave or shameless.

TheFlyingDutchman

unread,
Apr 23, 2011, 3:49:37 AM4/23/11
to
On Apr 22, 8:10 pm, Tim X <t...@nospam.dev.null> wrote:
When I see (let) described as creating lexical variables, I want it to
create lexical variables. Every time. While that feeling is not shared
by a majority of people on this newsgroup, I can take comfort in
knowing that it was shared by a majority of the people on the ISLisp
Specification Committee.

WJ

unread,
Apr 23, 2011, 3:53:57 AM4/23/11
to
Pascal J. Bourguignon wrote:

> RG <rNOS...@flownet.com> writes:
>
> > Suppose I want to make a lexical closure. I type this:
> >
> > (let ((v 0))
> > (lambda () (incf v)))
> >
> > But that may or may not give me a lexical closure depending on whether
> > or not at some previous point in this current session someone has typed

> > (defvar v ...) or some such thing. This is why the earmuffs

> > convention was developed, but any time you have to have a rule like that
> > it's an indication of a poor design. If all special variables should
> > have earmuffs, why not build that into the language spec?
> >
> > The answer is that DEFVAR works the way it does not because it's a good
> > design, but because part of CL's mission statement was to unify
> > dynamically and lexically scoped lisps. But no one uses dynamically
> > scoped Lisps any more,
>
> emacs lisp.
>
>
> > so we are saddled with a bad design that was put in place to satisfy
> > a requirement that no one cares about any more.
>
> Thanks to this design choice, you can easily run emacs lisp code on any
> CL implementation. :-)

A toadeater was a charlatan's helper whose job it was to eat toads.

Today, he calls himself Pascal and fervently defends every absurdity
of the travesty known as COBOL-Lisp.

WJ

unread,
Apr 23, 2011, 4:22:42 AM4/23/11
to
TheFlyingDutchman wrote:

The majority of the "people" on this newsgroup are mindless
sycophants and servile toadeaters. They salivate over every
large, hairy wart on the back of COBOL-Lisp. To expect
honesty or rationality from them is like expecting elephant dung
to smell sweet.


(defvar a 'special)
(defun foo () (setq a 'set-by-foo))
(defvar closure
(let ((a 'local))


(print a)
(foo)
(print a)

(lambda () (setq a 'set-by-closure))))
(funcall closure)
(print a)

==>

LOCAL
SET-BY-FOO
SET-BY-CLOSURE

Bernard Lang:

Common Lisp did kill Lisp. Period. (just languages take a
long time dying ...) It is to Lisp what C++ is to C. A
monstrosity that totally ignores the basics of language
design, simplicity and orthogonality to begin with.


-----

Gilles Kahn:

To this day I have not forgotten that Common Lisp killed
Lisp, and forced us to abandon a perfectly good system,
LeLisp.

-----


Paul Graham, May 2001:

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

-----


Dick Gabriel:

Common Lisp is a significantly ugly language. If Guy and I
had been locked in a room, you can bet it wouldn't have
turned out like that.


-----

Jeffrey M. Jacobs:


Common LISP is the PL/I of Lisps. Too big and too
incomprehensible, with no examination of the real world of
software engineering.

... The CL effort resembles a bunch of spoiled children,
each insisting "include my feature or I'll pull out, and
then we'll all go down the tubes". Everybody had vested
interests, both financial and emotional.

CL is a nightmare; it has effectively killed LISP
development in this country. It is not commercially viable
and has virtually no future outside of the traditional
academic/defense/research arena.

TheFlyingDutchman

unread,
Apr 23, 2011, 4:30:19 AM4/23/11
to
On Apr 22, 5:07 pm, t...@sevak.isi.edu (Thomas A. Russ) wrote:

> TheFlyingDutchman <zzbba...@aol.com> writes:
>
> > > > It would seem that a let modifying a global variable temporarily in
> > > > order to provide a lexical variable is an implementation detail. Does
> > > > the specification require what you said, and if so, is there a reason
> > > > for that?
>
> > > A global variable, or more precisely a special variable is treated
> > > specially by LET. Ž In particular, LET does not change a special variable
> > > into a lexical variable. Ž It leaves it as a special variable, but
> > > affects the value.
>
> > This is a very confusing part of Common Lisp. Nothing about the name
> > "defvar" implies you are creating a "special variable" rather than a
> > global variable.
>
> Except for the first sentence in the description of DEFVAR in the
> specification:
>
>   "defparameter and defvar establish name as a dynamic variable."

"Nothing about the NAME defvar"

As in, it's not called defspecial.

It's likely anyone seeing "defspecial" is gonna ask "what is a special
variable". Whereas someone seeing "defvar" is likely gonna think "I
just defined a variable". But the difference between a global variable
and a dynamic variable declared at the highest level only comes about
with the behavior of let. (let) should be named
(declare_lexical_probably). With a name like this questions will have
to be asked, and answers will have to be given, however unpleasant.

The ANSI spec was also written in an unfortunate way in this area - it
used the non-computer science term "special variable" when it was (at
least per the glossary entry for special variable) referring to a
dynamic variable, something which IS known in computer science. But
then they decided that it would be better to intermingle the two
terms, as demonstrated in the phrase that you quoted - "defparameter


and defvar establish name as a dynamic variable".

>
> http://www.lispworks.com/documentation/HyperSpec/Body/m_defpar.htm#de...


>
> That clearly indicates that a dynamic variable is created.

But I think you would have to agree that it doesn't clearly indicate
that a "special variable" is created (the term I used).


> > And "special variable" is an unfortunate term,
> > particulary in light of the fact that it's glossary definition in the
> > CLHS is:
>
> > "special variable n. Trad. a dynamic variable."
>
> > So the glossary implies that dynamic variable is a better term than
> > special variable, and I bet anyone who hasn't been using Common Lisp
> > for years would agree.
>
> Quite possibly.  On the other hand, the name of the declaration that you
> use to create a "dynamic variable" is named "special".  So at some point
> you are forced to confront the use of both "dynamic" and "special" to
> name the phenomenon.

Doesn't (defvar) create a special variable (and the most common way to
do so)?

>
> > > LET introduces variables which will either be lexical or special.
> > > Absent any other declarations, the variables introduced by LET will be
> > > lexical variables. Ž But if there is a special declaration for that
> > > symbol, either globally or with a more limited scope, then the variable
> > > will be special.
>
> > Thanks, I see that now. Would much prefer let was always lexical.
>
> I suppose.  It would necessitate introducing a new binding form for

> special variables, then.  And it would make interleaving LET* type


> bindings for lexical and special variables a bit more difficult.
>
> But in practice this isn't really a problem, largely because just about
> everyone follows the special/dynamic variable naming convention.  So you
> just don't end up with name conflicts between dynamic and lexical
> variables.  Since in practice this is a non-issue, you won't find much
> interest in changing this.

I don't expect it (or most things I gripe about for that matter) to
change. But they did change it in ISLisp (which mirrors Common Lisp
most of the time).

WJ

unread,
Apr 23, 2011, 4:30:30 AM4/23/11
to
WJ wrote:

>
> (defvar a 'special)
> (defun foo () (setq a 'set-by-foo))
> (defvar closure
> (let ((a 'local))
> (print a)
> (foo)
> (print a)
> (lambda () (setq a 'set-by-closure))))
> (funcall closure)
> (print a)
>
> ==>
>
> LOCAL
> SET-BY-FOO
> SET-BY-CLOSURE


Gambit Scheme:


(define a 'global)
(define (foo) (set! a 'set-by-foo))
(define closure
(let ((a 'local))
(println a)
(foo)
(println a)
(lambda () (set! a 'set-by-closure))))
(closure)
(println a)

==>

local
local
set-by-foo

Teemu Likonen

unread,
Apr 23, 2011, 4:31:29 AM4/23/11
to
* 2011-04-23T00:49:37-07:00 * TheFlyingDutchman wrote:

> When I see (let) described as creating lexical variables, I want it to
> create lexical variables. Every time.

The description is correct. LET is described as creating lexical _or_
special (dynamic) bindings. Nobody is cheating you.

[...] each binding is lexical unless there is a special declaration
to the contrary.

http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm

> While that feeling is not shared by a majority of people on this

> newsgroup, [...]

I wonder how many people makes the majority here and how you measured
the majority's opinion.

Tim X

unread,
Apr 23, 2011, 4:57:56 AM4/23/11
to
RG <rNOS...@flownet.com> writes:

OK, I hadn't thought about how this impacts on the creation of a closure.
Seems like a valid point. Maybe I'm just use to how it currently is, but
what would be your alternative 'better' design? Remove dynamic/special
variables altogether or something else?

Tim

P.S. BTW, some of us stil do use dynamically scoped lisp dialects - for
example emacs lisp. It was also the first lisp dialect I used and does
not support closures (due to its limied extent).

Tim X

unread,
Apr 23, 2011, 5:25:59 AM4/23/11
to
TheFlyingDutchman <zzbb...@aol.com> writes:

I don't know how you come to the conclusion that something is or is not
shared by a majority when it isn't at all clear what it is that is being
said (ignoring how you assess what is a majority).

I guess there are differences in how we read the specification or
descriptions of let. The descriptions of let which I've read (for me)
make it quite clear that let creates lexical bindings UNLESS there is a
special declaration to the contrary. This doesn't imply or should not
assume that I agree with or think this is the best possible behaviour,
only that this is the specification and defined behaviour for this
language. Other lisp implementations may have different
specifications/behaviour, but then they would not be CL.

My original question was to try and understand what it was you found
indefensible with the example you provided as it seemed to fit perfectly
well with how I understood things work within CL. What it now seems
clear is what you are actually saying is that you don't like the way CL
defines how a language wih both dynamic and lexical scoping works. What
I was interested in is how you think such a language should work or are
ou syaing that it should just have one or the other?

Pascal J. Bourguignon

unread,
Apr 23, 2011, 5:55:30 AM4/23/11
to
Tim X <ti...@nospam.dev.null> writes:

> OK, I hadn't thought about how this impacts on the creation of a closure.
> Seems like a valid point. Maybe I'm just use to how it currently is, but
> what would be your alternative 'better' design? Remove dynamic/special
> variables altogether or something else?

ISLisp uses a specific syntax:

>> > (defvar a 10)
>> > (defun foo () (setq a -10))
>> > (let ((a 20)) (foo) (print a) ) => -10

>> > a

would be written:

(defdynamic a 42)
(defun foo () (setf (dynamic a) -10))
(dynamic-let ((a 20))
(foo)
(dynamic a))
(dynamic a)


It is trivial to implement the same syntax in CL:

(eval-when (:execute :compile-toplevel :load-toplevel)
(defun earmuff (name) (intern (format nil "*~A*" name) (symbol-package
name))))

(defmacro defdynamic (name value) ; no documentation in ISLisp
`(defvar ,(earmuff name) ,value))

(defmacro dynamic-let (bindings &body body)
`(let ,(mapcar (lambda (binding) ; no optional init in ISLisp
(destructuring-bind (name value) binding
`(,(earmuff name) ,value)))
bindings)
,@body))

(defmacro dynamic (name) (earmuff name))


Global lexical variables are more technical, but as easy to implement in
CL. Check cll old discussions about both subjects!


> P.S. BTW, some of us stil do use dynamically scoped lisp dialects - for
> example emacs lisp. It was also the first lisp dialect I used and does
> not support closures (due to its limied extent).

--

TheFlyingDutchman

unread,
Apr 23, 2011, 6:36:54 AM4/23/11
to
> Global lexical variables are more technical, but as easy to implement in
> CL.  Check cll old discussions about both subjects!

http://www.cl-user.net/asp/d9at1/sdataQ19DcvSkO1ArDQ3wzR8X8yBX8yBXnMq=/sdataQu3F$sSHnB==

Authors and Maintainers

Tim Bradshaw

Pascal Costanza

unread,
Apr 23, 2011, 6:37:57 AM4/23/11
to

First of all, "v" is a bad variable name anyway.

Secondly, I recall reading a post by Kent Pitman that it was actually
considered to enforce the naming convention for special variables, but
that it was dropped for some reason (but I forgot what the reason was).

ISLISP indeed has a better design for special variables, where they have
their own namespace. But Common Lisp's design is not that bad after all.
The parameters in the R7RS draft also look quite good.

> The answer is that DEFVAR works the way it does not because it's a good
> design, but because part of CL's mission statement was to unify
> dynamically and lexically scoped lisps. But no one uses dynamically
> scoped Lisps any more, so we are saddled with a bad design that was put
> in place to satisfy a requirement that no one cares about any more.

Everybody uses dynamic scoping in one way or the other. Not as a
default, but in special cases.

Pascal Costanza

unread,
Apr 23, 2011, 6:39:28 AM4/23/11
to
On 23/04/2011 11:55, Pascal J. Bourguignon wrote:
> Tim X<ti...@nospam.dev.null> writes:
>
>> OK, I hadn't thought about how this impacts on the creation of a closure.
>> Seems like a valid point. Maybe I'm just use to how it currently is, but
>> what would be your alternative 'better' design? Remove dynamic/special
>> variables altogether or something else?
>
> ISLisp uses a specific syntax:
>
>>>> (defvar a 10)
>>>> (defun foo () (setq a -10))
>>>> (let ((a 20)) (foo) (print a) ) => -10
>>>> a
>
> would be written:
>
> (defdynamic a 42)
> (defun foo () (setf (dynamic a) -10))
> (dynamic-let ((a 20))
> (foo)
> (dynamic a))
> (dynamic a)
>
>
> It is trivial to implement the same syntax in CL:
>
> (eval-when (:execute :compile-toplevel :load-toplevel)
> (defun earmuff (name) (intern (format nil "*~A*" name) (symbol-package
> name))))
>
> (defmacro defdynamic (name value) ; no documentation in ISLisp
> `(defvar ,(earmuff name) ,value))
>
> (defmacro dynamic-let (bindings&body body)

> `(let ,(mapcar (lambda (binding) ; no optional init in ISLisp
> (destructuring-bind (name value) binding
> `(,(earmuff name) ,value)))
> bindings)
> ,@body))
>
> (defmacro dynamic (name) (earmuff name))
>
>
> Global lexical variables are more technical, but as easy to implement in
> CL. Check cll old discussions about both subjects!

You can also check ContextL, which provides an implementation of the
ISLISP forms for dynamic variables, plus provides a way to capture
first-class (full and partial) dynamic environments.

TheFlyingDutchman

unread,
Apr 23, 2011, 6:47:50 AM4/23/11
to
On Apr 23, 1:31 am, Teemu Likonen <tliko...@iki.fi> wrote:
> * 2011-04-23T00:49:37-07:00 * TheFlyingDutchman wrote:
>
> > When I see (let) described as creating lexical variables, I want it to
> > create lexical variables. Every time.
>
> The description is correct. LET is described as creating lexical _or_
> special (dynamic) bindings. Nobody is cheating you.
>
> [...] each binding is lexical unless there is a special declaration
> to the contrary.
>
> http://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm

I was thinking more of textbook description of (let), but I can't find
any, or even general descriptions of Common Lisp local variables that
only mention lexical. I guess I either didn't process the
qualification whenever I had looked at a description of (let) or never
read the full description in the first place.

Does the spec adequately address what behavior a (let) variable has
when there has been a previous defvar? It seems that the behavior it
demonstrates would be characterized as "creating a local dynamic
variable", rather than just deferring to a previous declaration of a
dynamic variable.

>
> > While that feeling is not shared by a majority of people on this
> > newsgroup, [...]
>
> I wonder how many people makes the majority here and how you measured
> the majority's opinion.

I would say for any given week there are about a dozen posters.
Although as you may imply, it is hard to calculate who might be
"lurking" in that week. I did assume that absent any response, their
opinion is in favor of the status quo. Perhaps that is incorrect,
especially in light of RG posting a criticism.

Rob Warnock

unread,
Apr 23, 2011, 7:04:28 AM4/23/11
to
Thomas A. Russ <t...@sevak.isi.edu> wrote:
+---------------
| How this is represented internally is not specified. That is an
| implementation detail left up to the discretion of the implementation.
| All that the specification itself requires is that a symbol object be
| able to return the appropriate values for SYMBOL-NAME, SYMBOL-PACKAGE,
| SYMBOL-VALUE, SYMBOL-FUNCTION, etc.
|
| These do not have to be implemented as slots. It would be perfectly
| conforming for an implementation to create a symbol object with no slots
| whatsoever and implement everything with, for example, hash tables. Or
| an implementation could take a hybrid approach and have some slots and
| some tables.
+---------------

And, in fact, CMUCL uses exactly such a hybrid approach. Symbols
in CMUCL have a value slot and a plist slot, but no function slot.

[Functions are stored in the CMUCL-specific "info" database, which
to a first approximation is a hash table of hash tables. (Sort of.)]


-Rob

-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <http://rpw3.org/>
San Mateo, CA 94403

It is loading more messages.
0 new messages