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

Simple newbie list processing troubble

21 views
Skip to first unread message

Peder Y

unread,
Sep 28, 2002, 5:04:57 AM9/28/02
to
Say I have a function foo that is supposed to take a list as input (A
B C D...). The function will then traverse the list looking for an
element, and change that element. That's basically it.

For example, say, the function shall set all elements of lst to 'A:
Why is this wrong?

(defun foo (lst)
(loop for x in lst do
(setf (car x) 'A)))

- Peder -

Adam Warner

unread,
Sep 28, 2002, 7:06:58 AM9/28/02
to
Hi Peder Y,

Unless you have a particular need to perform destructive modification of
the input list Peder just create another list:

(defun foo (list)
(loop for x in list collect 'A))

You tried to find the car of a symbol. As you loop through the list x
contains elements of the list.

[1]> (setf list '(a b c d))
(A B C D)
[2]> (listp list)
T
[3]> (listp (first list))
NIL

Regards,
Adam

Paul F. Dietz

unread,
Sep 28, 2002, 8:03:23 AM9/28/02
to
Peder Y wrote:

> For example, say, the function shall set all elements of lst to 'A:
> Why is this wrong?
>
> (defun foo (lst)
> (loop for x in lst do
> (setf (car x) 'A)))

This loops over the contents of the list, not over the
cons cells of the list. X takes on the values A, B, etc.
which are not cons cells.

To get the effect you want we can change one character:

(defun foo (lst)
(loop for x on lst do
(setf (car x) 'A)))

Here, X takes on the values (A B C D ...), (B C D ...), etc.

Btw, use of the name 'lst' marks you as a Schemer. :)

Paul

Bruce Hoult

unread,
Sep 28, 2002, 9:55:23 AM9/28/02
to
In article <3D959BFC...@dls.net>, "Paul F. Dietz" <di...@dls.net>
wrote:

> Btw, use of the name 'lst' marks you as a Schemer. :)

Paul Graham uses "lst" throughout _On Lisp_, from the tutorial section
to the mini-CLOS implementation at the end.

-- Bruce

Erik Naggum

unread,
Sep 28, 2002, 10:05:58 AM9/28/02
to
* Paul F. Dietz

| Btw, use of the name 'lst' marks you as a Schemer. :)

* Bruce Hoult


| Paul Graham uses "lst" throughout _On Lisp_, from the tutorial section to
| the mini-CLOS implementation at the end.

I read this as affirming Paul's point. But why bother affirming it, so I
think perhaps you meant to contradict it. Would you care to explain why you
think «On Lisp» is not an effort to bring some of Scheme into Common Lisp?
(Please note that he has said so himself.)

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Bruce Hoult

unread,
Sep 28, 2002, 10:32:46 AM9/28/02
to
In article <32422107...@naggum.no>, Erik Naggum <er...@naggum.no>
wrote:

> * Paul F. Dietz
> | Btw, use of the name 'lst' marks you as a Schemer. :)
>
> * Bruce Hoult
> | Paul Graham uses "lst" throughout _On Lisp_, from the tutorial section to
> | the mini-CLOS implementation at the end.
>
> I read this as affirming Paul's point. But why bother affirming it, so I
> think perhaps you meant to contradict it. Would you care to explain why you
> think «On Lisp» is not an effort to bring some of Scheme into Common Lisp?
> (Please note that he has said so himself.)

He has? Where?

Certainly, the chapter on getting many of the effects of call/cc in CL
(by defining macros such as =defun, =values, etc that manipulate
explicitly-passed continuations) would qualify as an effort to bring
*some* of Scheme into Common Lisp.

On the other hand, it's also an illustration that you don't necessarily
need those features built in if you can implement them yourself using a
sufficiently powerful macro system.

In fact that appears to be the point of the whole book. That CL's
powerful macros are the prime thing that distinguishes it from lesser
languages, such as Scheme.

Is that the sort of thing a "Schemer" would do?

-- Bruce

Marco Antoniotti

unread,
Sep 28, 2002, 1:10:33 PM9/28/02
to

pyd...@ec.auckland.ac.nz (Peder Y) writes:

The above will not necessarily work because you are changing the list
as you are traversing it. This is specifically mentioned in the
language standard.

To do that kind of things you should look to the standard functions
SUBSTITUTE and NSUBSTITUTE.

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Erik Naggum

unread,
Sep 28, 2002, 2:40:34 PM9/28/02
to
* Bruce Hoult <br...@hoult.org>

| Is that the sort of thing a "Schemer" would do?

It is the sort of thing that somebody who likes Scheme better than Common
Lisp would do.

--
Erik Naggum, Oslo, Norway Today, the sum total of the money I
would retain from the offers in the
more than 7500 Nigerian 419 scam letters received in the past 33 months would
have exceeded USD 100,000,000,000. You can stop sending me more offers, now.

Bruce Hoult

unread,
Sep 28, 2002, 8:19:51 PM9/28/02
to
In article <32422272...@naggum.no>, Erik Naggum <er...@naggum.no>
wrote:

> * Bruce Hoult <br...@hoult.org>


> | Is that the sort of thing a "Schemer" would do?
>
> It is the sort of thing that somebody who likes Scheme better than Common
> Lisp would do.

Seems to me that person would actually write a book called _On Scheme_,
which showed how to implement features they liked from Common Lisp and
Prolog on top of Scheme.

-- Bruce

Barry Margolin

unread,
Sep 30, 2002, 11:31:08 AM9/30/02
to
In article <y6cvg4q...@octagon.valis.nyu.edu>,

Marco Antoniotti <mar...@cs.nyu.edu> wrote:
>
>pyd...@ec.auckland.ac.nz (Peder Y) writes:
>
>> Say I have a function foo that is supposed to take a list as input (A
>> B C D...). The function will then traverse the list looking for an
>> element, and change that element. That's basically it.
>>
>> For example, say, the function shall set all elements of lst to 'A:
>> Why is this wrong?
>>
>> (defun foo (lst)
>> (loop for x in lst do
>> (setf (car x) 'A)))
>
>The above will not necessarily work because you are changing the list
>as you are traversing it. This is specifically mentioned in the
>language standard.

I haven't checked the reference, but I'm pretty sure this is a case that's
specifically *allowed* by the standard. When traversing a list, it's OK to
modify the CAR of the current element, but not the CDRs.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Michael Hudson

unread,
Sep 30, 2002, 11:39:28 AM9/30/02
to
Barry Margolin <bar...@genuity.net> writes:
> In article <y6cvg4q...@octagon.valis.nyu.edu>,
> Marco Antoniotti <mar...@cs.nyu.edu> wrote:
> >pyd...@ec.auckland.ac.nz (Peder Y) writes:
> >> For example, say, the function shall set all elements of lst to 'A:
> >> Why is this wrong?
> >>
> >> (defun foo (lst)
> >> (loop for x in lst do
> >> (setf (car x) 'A)))
> >
> >The above will not necessarily work because you are changing the list
> >as you are traversing it. This is specifically mentioned in the
> >language standard.
>
> I haven't checked the reference, but I'm pretty sure this is a case that's
> specifically *allowed* by the standard. When traversing a list, it's OK to
> modify the CAR of the current element, but not the CDRs.

As posted, it's just bust. If it were (loop for x ON lst do ...),
then I think it's OK by the standard. Section 3.6 ("Traversal Rules
and Side Effects") says:

List traversal
For list traversal operations, the cdr chain of the list is not
allowed to be destructively modified.

Which suggests to me that mutating the CAR is OK.

Cheers,
M.

--
The Programmer's Quick Guide To Python (Time Machine version):
You try to shoot yourself in the foot, only to realize that
there's no need, since Guido thoughtfully shot you in the foot
years ago. -- Nick Mathewson, comp.lang.python

Marco Antoniotti

unread,
Sep 30, 2002, 12:01:36 PM9/30/02
to

Michael Hudson <m...@python.net> writes:

> Barry Margolin <bar...@genuity.net> writes:
> > In article <y6cvg4q...@octagon.valis.nyu.edu>,
> > Marco Antoniotti <mar...@cs.nyu.edu> wrote:

...


> >
> > I haven't checked the reference, but I'm pretty sure this is a case that's
> > specifically *allowed* by the standard. When traversing a list, it's OK to
> > modify the CAR of the current element, but not the CDRs.
>
> As posted, it's just bust. If it were (loop for x ON lst do ...),
> then I think it's OK by the standard. Section 3.6 ("Traversal Rules
> and Side Effects") says:
>
> List traversal
> For list traversal operations, the cdr chain of the list is not
> allowed to be destructively modified.
>
> Which suggests to me that mutating the CAR is OK.

Thanks to you and Barry. It does look like changing the CAR of a list
while traversing is ok.

Erik Naggum

unread,
Sep 30, 2002, 2:50:57 PM9/30/02
to
* Peder Y

| (defun foo (lst)
| (loop for x in lst do
| (setf (car x) 'A)))

* Marco Antoniotti


| The above will not necessarily work because you are changing the list as you
| are traversing it. This is specifically mentioned in the language standard.

Huh? The only way the above code would work is by changing the car of each
cons cell that is the car of the cons cells that are traversed. This is not
even close to the restriction of modifying the list structure itself, which
also means the cdr. But even (cdr x) would be just fine, because it would
only modify the conses that were the elements of the list.

In particular, after (foo bar), bar would have a contents like
((A ...) (A ...) (A ...) ...).

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.

Marco Antoniotti

unread,
Sep 30, 2002, 4:13:31 PM9/30/02
to

Erik Naggum <er...@naggum.no> writes:

> * Peder Y
> | (defun foo (lst)
> | (loop for x in lst do
> | (setf (car x) 'A)))
>
> * Marco Antoniotti
> | The above will not necessarily work because you are changing the list as you
> | are traversing it. This is specifically mentioned in the language standard.
>
> Huh? The only way the above code would work is by changing the car of each
> cons cell that is the car of the cons cells that are traversed. This is not
> even close to the restriction of modifying the list structure itself, which
> also means the cdr. But even (cdr x) would be just fine, because it would
> only modify the conses that were the elements of the list.
>
> In particular, after (foo bar), bar would have a contents like
> ((A ...) (A ...) (A ...) ...).

Yep. My mistake.

Dorai Sitaram

unread,
Oct 1, 2002, 4:39:17 PM10/1/02
to
In article <bruce-C9E44F....@copper.ipg.tsnz.net>,

Paul Graham's use of "lst" is probably because he wants
to keep his code usable, with minimal or automatable
translation, in Scheme also. Which would help those
who are using his book privately to learn Lisp
principles but trying out his examples in Scheme. I've
seen this kind of honorable eclecticism in other books
too, notably the Little Schemer, where footnotes
quietly identify how to run the examples in
Common Lisp.

Are there any CL tutorial books that actually advise
using the same symbol for both its symbol-value and its
symbol-function (holding different values)? I have
seen at least one -- I think it was the Winston and
Horn -- that counseled against this practice
because it is "confusing"!!! Perhaps they have the
same rationale as Graham, because in the streams (as in
delayed lists, not ports) chapter, they explicitly
mention, somewhat ruefully, that Scheme streams would
have a cleaner syntax.

Erik Naggum

unread,
Oct 1, 2002, 6:01:31 PM10/1/02
to
* Dorai Sitaram

| Are there any CL tutorial books that actually advise using the same
| symbol for both its symbol-value and its symbol-function (holding
| different values)?

But that is not what anyone argues for. Lexical bindings do not affect
the symbol-value of a the symbol used. Some precision here is good.

Carl Shapiro

unread,
Oct 1, 2002, 9:10:06 PM10/1/02
to
ds...@goldshoe.gte.com (Dorai Sitaram) writes:

I have
> seen at least one -- I think it was the Winston and
> Horn -- that counseled against this practice
> because it is "confusing"!!!

More timeless advice from the people who'd like to you belive that use
of CAR and CDR has largely disappeared in favor of FIRST and REST.

Yawn.

Adam Warner

unread,
Oct 2, 2002, 12:54:17 AM10/2/02
to
Hi Dorai Sitaram,

I love the freedom of separate namespaces. But perhaps I can receive some
help on a related question.

I am updating syntax and function names on a regular basis in the document
format I'm developing. So that legacy documents don't have to be manually
updated I upgrade them automatically. I love the way I can read in lists
of Lisp code as data and process them without operating on the code at the
character level (and I set *print-case* to :downcase so the updated code
doesn't start shouting).

But how should I proceed with automatically updating code when a
variable/symbol name may be the same as a function name and I only want to
update the function name (or vice versa)? Is there any built-in way to
find out whether something is referring to a function/macro or do I have
to parse the syntax manually (for example noting that a particular list is
quoted and therefore the symbol at the start of a list doesn't refer to a
function).

In Richard C. Waters Macroexpand-All: An Example of a Simple Lisp Code
Walker http://www.merl.com/papers/TR93-17/ it states that there are 25
special forms and each has its own special semantics. It seems that if I
want to be able to robustly update code that I have to understand many of
these special forms so I do not accidentally modify a variable name
instead of a non-function name with the same name, etc. (it's similar to
the list/list issue).

Maybe a simple example could focus the question:

(let ((list (list '(list 'list))))
(write (list list))
(write '(list list)))

What would be the robust way of processing this code so that only the
function name list is changed to newlist? Some of the difficulty in
parsing this code arises out of the separate namespaces.

Regards,
Adam

Coby Beck

unread,
Oct 2, 2002, 1:45:19 AM10/2/02
to

"Adam Warner" <use...@consulting.net.nz> wrote in message
news:andu5q$dgso2$1...@ID-105510.news.dfncis.de...

>
> I am updating syntax and function names on a regular basis in the document
> format I'm developing. So that legacy documents don't have to be manually
> updated I upgrade them automatically. I love the way I can read in lists
> of Lisp code as data and process them without operating on the code at the
> character level (and I set *print-case* to :downcase so the updated code
> doesn't start shouting).
>
> But how should I proceed with automatically updating code when a
> variable/symbol name may be the same as a function name and I only want to
> update the function name (or vice versa)? Is there any built-in way to

[snip]

> Maybe a simple example could focus the question:
>
> (let ((list (list '(list 'list))))
> (write (list list))
> (write '(list list)))
>
> What would be the robust way of processing this code so that only the
> function name list is changed to newlist? Some of the difficulty in
> parsing this code arises out of the separate namespaces.

While I always hesitate to say anything is impossible, I don't see how this
could be. Even the almighty human brain can not look at that and make the
substitution without knowing what the semantics of your application are.
How can I know that '(list list) or 'list is data, not code? Being quoted
does not prove that, as you said code is data in lisp. What about (mapcar
'list ...)?

I think the best you could do would be a naive approach that assumed no code
is being passed around as data and no functions are passed symbols instead
of function objects (ie #'list), then you could globally replace all
occurences of <(target > and <#'target > with many messy exceptions (like
LET ...)


--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")


Tim Bradshaw

unread,
Oct 2, 2002, 3:11:10 AM10/2/02
to
* Adam Warner wrote:

> Maybe a simple example could focus the question:

> (let ((list (list '(list 'list))))
> (write (list list))
> (write '(list list)))

> What would be the robust way of processing this code so that only the
> function name list is changed to newlist? Some of the difficulty in
> parsing this code arises out of the separate namespaces.

You need a code walker. This has to understand all the special forms
defined by the language, as well as being able to do full
macroexpansion. For instance, it needs to know that if I've said:

(defmacro bind ((var val) &body forms)
`(let ((,var ,val)) ,@forms))

(bind (list 1)
list)

That the occurrence of LIST isn't a function call. The way to know
this is to do macroexpansion.

Note that the code walker needs to take note of macros you define as
well as CLs. Partly this can be done by just assuming that you've
already loaded your system, but even this is not quite enough:

(macrolet ((bind ((var val)) &body forms)
`(let ((,var ,val)) ,@forms))
(bind (list 1)
list))

It's quite hard to get this completely right.

--tim

Adam Warner

unread,
Oct 2, 2002, 4:00:56 AM10/2/02
to
Hi Coby Beck,

>> (let ((list (list '(list 'list))))
>> (write (list list))
>> (write '(list list)))
>>
>> What would be the robust way of processing this code so that only the
>> function name list is changed to newlist? Some of the difficulty in
>> parsing this code arises out of the separate namespaces.
>
> While I always hesitate to say anything is impossible, I don't see how
> this could be. Even the almighty human brain can not look at that and
> make the substitution without knowing what the semantics of your
> application are. How can I know that '(list list) or 'list is data, not
> code? Being quoted does not prove that, as you said code is data in
> lisp. What about (mapcar 'list ...)?
>
> I think the best you could do would be a naive approach that assumed no
> code is being passed around as data and no functions are passed symbols
> instead of function objects (ie #'list), then you could globally replace
> all occurences of <(target > and <#'target > with many messy exceptions
> (like LET ...)

Thanks for the insights Coby. I would hesitate to say it is impossible
because it must be possible to trace back from the function calls to what
generated them. But I see now that it would require something many times
more complicated and intelligent than the original interpreter/compiler.
To give another example from your insights, what sort of AI would be able
to deduce that this code:

(funcall (read-from-string (coerce (list (code-char 76) (code-char 73)
(code-char 83) (code-char 84)) 'string)) 'list)

...(using ASCII/UTF-8 character codes) should be changed to:

(newlist 'list)

[To change all list function calls to newlist in the contrived example]

Naive approach methinks (or explicit version control).

Regards,
Adam

Adam Warner

unread,
Oct 2, 2002, 4:08:50 AM10/2/02
to
Hi Tim Bradshaw,

Thanks for how this would be approached Tim. Analysing Richard Waters'
macroexpand-all code would be a good start.

Given the example I just posted it would be impractical to get it
completely right.

Regards,
Adam

Eric Marsden

unread,
Oct 2, 2002, 5:35:58 AM10/2/02
to
>>>>> "aw" == Adam Warner <use...@consulting.net.nz> writes:

aw> Maybe a simple example could focus the question:
aw>
aw> (let ((list (list '(list 'list))))
aw> (write (list list))
aw> (write '(list list)))
aw>
aw> What would be the robust way of processing this code so that only the
aw> function name list is changed to newlist? Some of the difficulty in
aw> parsing this code arises out of the separate namespaces.

Here is how to do this using the PCL code walker (available with
CMUCL). The walker allows you to distinguish between uses of the
symbol list as a function and as data, including Tim's example of a
macro that changes the symbol binding. However, it won't detect uses
of the list function via FUNCALL; that requires whole program analysis
in the general case.

,----
| USER> (defvar *walker-demo-form*
| (read-from-string
| "(let ((list (list 'list '(list 'list))))
| (write (list list))
| (write (funcall 'list list))
| (write '(list list)))"))
| *walker-demo-form*
| USER> (defun walker-demo (form)
| (flet ((walk-function (form context env)
| (declare (ignorable env))
| (cond ((not (eq context :eval)) form)
| ((not (listp form)) form)
| ((and (symbolp (first form))
| (fboundp (first form))
| (eq 'list (first form)))
| (cons 'newlist (rest form)))
| (t form))))
| (walker:walk-form form nil #'walk-function)))
| walker-demo
| USER> (walker-demo *walker-demo-form*)
| (let ((list (newlist 'list '(list 'list))))
| (write (newlist list))
| (write (funcall 'list list))
| (write '(list list)))
| USER> (defmacro bind ((var val) &body forms)
| `(let ((,var ,val)) ,@forms))
| bind
| USER> (walker-demo '(bind (list 1) list))
| (bind (list 1) list)
`----

--
Eric Marsden <URL:http://www.laas.fr/~emarsden/>

Alan S. Crowe

unread,
Oct 2, 2002, 6:42:57 AM10/2/02
to
To: Erik Naggum <er...@naggum.no>
Subject: Re: Simple newbie list processing troubble
References: <10b28c6c.02092...@posting.google.com> <3D959BFC...@dls.net> <bruce-C9E44F....@copper.ipg.tsnz.net> <and15l$bjp$1...@news.gte.com> <32424984...@naggum.no>
--text follows this line--

Erik Naggum writes:
> Lexical bindings do not affect the symbol-value of a the
> symbol used.

* (defvar x 137)
X

* x
137

* (let ((x 'dragon))
(list
x
(symbol-value 'x)))

(DRAGON DRAGON)

err, um, I expected (DRAGON 137)

* x
137

Well my old value of x is still there, so a symbol must have
multiple "symbol values", even when it is special. This
needs more investigation.

Alan Crowe, Edinburgh, Scotland

Frode Vatvedt Fjeld

unread,
Oct 2, 2002, 7:00:37 AM10/2/02
to
al...@cawtech.freeserve.co.uk (Alan S. Crowe) writes:

> err, um, I expected (DRAGON 137)

What (defvar <x> ..) does, among other things, is to proclaim <x> to
be a special variable. One consequence of this is that it will be
_impossible_ to create a lexical binding for <x>. So when (let ((<x>
..)) is later evaluated or compiled, a dynamic binding is created.

> Well my old value of x is still there, so a symbol must have
> multiple "symbol values", even when it is special.

Each symbol has as many symbol-values as it has bindings in a
particular (dynamic) scope. But only the last/innermost binding's
value is available to you.

--
Frode Vatvedt Fjeld

Edi Weitz

unread,
Oct 2, 2002, 7:07:05 AM10/2/02
to
al...@cawtech.freeserve.co.uk (Alan S. Crowe) writes:

> * (defvar x 137)
> X
>
> * x
> 137
>
> * (let ((x 'dragon))
> (list
> x
> (symbol-value 'x)))
>
> (DRAGON DRAGON)
>
> err, um, I expected (DRAGON 137)
>
> * x
> 137
>
> Well my old value of x is still there, so a symbol must have
> multiple "symbol values", even when it is special. This
> needs more investigation.

X is globally special because you used DEFVAR. Therefore your LET
binds the dynamic variable X to a new value during the execution of
this form.

Consider this:

(defun foo1 ()
(declare (special x))
(let ((x 42))
(list x (symbol-value 'x))))

(defun foo2 ()
(let ((x 42))
(declare (special x))
(list x (symbol-value 'x))))

(defun bar (function)
(let ((x 'frob))
(declare (special x))
(funcall function)))

* (bar #'foo1)
(42 FROB)
* (bar #'foo2)
(42 42)

Due to your DEFVAR you implicitely used the FOO2 mechanism where I
think you expected FOO1 behaviour.

Look at the entry for LET in the CLHS where it says that "each binding
is lexical unless there is a special declaration to the contrary". So
Erik Naggum was of course right when he said that lexical bindings do
not affect the SYMBOL-VALUE. However, your example wasn't about
lexical bindings.

Edi.

Will Deakin

unread,
Oct 2, 2002, 7:27:40 AM10/2/02
to
Alan S. Crowe wrote:
> Well my old value of x is still there, so a symbol must have
> multiple "symbol values", even when it is special. This
> needs more investigation.
This sounds to me like an issue with understanding scope and
extent[1]. I found this hard to understand and found that the biggest
help was reading chapter 3 of CLTL2[1] several times. (I also realise
that I am in danger of repeating myself...)

:)w

[1] The online version is available here (and other places):
www.ida.liu.se/imported/cltl/clm/clm.html

Will Deakin

unread,
Oct 2, 2002, 7:35:05 AM10/2/02
to
Will Deakin wrote:
> I found this hard to understand and found that the biggest help was
> reading chapter 3 of CLTL2[1] several times.
(...and chapter 5,7 and the index...)

;)w

Tim Bradshaw

unread,
Oct 2, 2002, 7:37:07 AM10/2/02
to
* Alan S Crowe wrote:

* (defvar x 137)
> X

* x
> 137

* (let ((x 'dragon))
> (list
> x
> (symbol-value 'x)))

That's not a lexical binding, it's a special binding. Once you've
done a DEFVAR on something it's special for ever - you can never make
it lexical again.

--tim

Dorai Sitaram

unread,
Oct 2, 2002, 8:52:28 AM10/2/02
to
In article <andu5q$dgso2$1...@ID-105510.news.dfncis.de>,

Adam Warner <use...@consulting.net.nz> wrote:
>
>(let ((list (list '(list 'list))))
> (write (list list))
> (write '(list list)))
>
>What would be the robust way of processing this code so that only the
>function name list is changed to newlist? Some of the difficulty in
>parsing this code arises out of the separate namespaces.

I didn't understand your motivation for this example,
but converting the example itself seems a lost cause.
Your only way out is to follow the Paul Graham tack of
scrupulously abstaining from the ability to use the
same symbol as both operator name and non-operator
variable. Once you do that, of course, you aren't
really exploiting the vaunted freedom of a Lisp2
anymore. You are writing as a Lisp1er (eg, Schemer)
would, except that, unlike them, you are still saddled
with the funcall/#' machinery even though it
isn't buying you anything in an informational sense.

Erik Naggum

unread,
Oct 2, 2002, 8:57:11 AM10/2/02
to
* Erik Naggum

| Lexical bindings do not affect the symbol-value of a the symbol used.

* Alan S. Crowe


| Well my old value of x is still there, so a symbol must have multiple
| "symbol values", even when it is special. This needs more investigation.

It is not a lexical binding when it is special. /THINK/!

Vassil Nikolov

unread,
Oct 2, 2002, 9:31:30 AM10/2/02
to
Frode Vatvedt Fjeld <fro...@cs.uit.no> writes:

> What (defvar <x> ..) does, among other things, is to proclaim <x> to
> be a special variable. One consequence of this is that it will be
> _impossible_ to create a lexical binding for <x>.

And which is also (one of the reasons) why it is (usually) a good idea
to have asterisks around the names of special variables. (Whether
global or not.)

---Vassil.


Tim Bradshaw

unread,
Oct 2, 2002, 11:06:31 AM10/2/02
to
* Dorai Sitaram wrote:

> I didn't understand your motivation for this example,
> but converting the example itself seems a lost cause.

This is obviously false. Anything which understands the code - such
as a correct code walker - can do this kind of replacement. One
canonical example of such a program is an interpreter or compiler, and
several Lisp environments have compilers which maintain databases of
where functions (and less commonly, but obviously possibly) variables
are used and provided user access to them. I think at least one
InterLisp system, for instance, allowed you to specify replacements on
programs, relying on this kind of information (and possibly also
allowing pattern-based substitutions too).

In general, I can't see the reason for changing lexically bound
variable names, since (in a Lisp2) they never really matter - the
exceptions being when you want to unify or split two variables. Those
exceptions can't really be done mechanically since they obviously
change the program semantics. Dynamic variables are clearly more
interesting to track (and not surprisingly the various
compiler/database systems do tend to track bindings of & references
too specials).

--tim


Joe Marshall

unread,
Oct 2, 2002, 11:50:28 AM10/2/02
to
Tim Bradshaw <t...@cley.com> writes:

> In general, I can't see the reason for changing lexically bound

> variable names...

Avoiding name collisions when inlining.

Tim Bradshaw

unread,
Oct 2, 2002, 12:20:14 PM10/2/02
to
* Joe Marshall wrote:

> Avoiding name collisions when inlining.

Oh, yes that's a very good reason. What I meant was as an editorial
change to source code, not as something done during
compilation/evaluation - sorry not to be clearer...

--tim

Erik Naggum

unread,
Oct 2, 2002, 7:05:16 PM10/2/02
to
* Dorai Sitaram

| I didn't understand your motivation for this example,
| but converting the example itself seems a lost cause.

If so, it would also be impossible to execute. Is it?

| Your only way out is to follow the Paul Graham tack of scrupulously
| abstaining from the ability to use the same symbol as both operator name
| and non-operator variable.

I think you should say "my only way out" when that is what you mean.

| You are writing as a Lisp1er (eg, Schemer) would, except that, unlike
| them, you are still saddled with the funcall/#' machinery even though it
| isn't buying you anything in an informational sense.

I think products and vendors should be judged by the intelligence of
their marketing. So Scheme must be the choice of the pretty dumb.

0 new messages