From: Peder Y
Subject: Simple newbie list processing troubble
Date: 
Message-ID: <10b28c6c.0209280104.52056c24@posting.google.com>
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 -

From: Paul F. Dietz
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3D959BFC.D1305E7D@dls.net>
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
From: Bruce Hoult
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <bruce-C9E44F.01552229092002@copper.ipg.tsnz.net>
In article <·················@dls.net>, "Paul F. Dietz" <·····@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
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242210758749239@naggum.no>
* 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.
From: Bruce Hoult
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <bruce-81037C.02324629092002@copper.ipg.tsnz.net>
In article <················@naggum.no>, Erik Naggum <····@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
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242227234320160@naggum.no>
* Bruce Hoult <·····@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.
From: Bruce Hoult
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <bruce-02CB8D.12195129092002@copper.ipg.tsnz.net>
In article <················@naggum.no>, Erik Naggum <····@naggum.no> 
wrote:

> * Bruce Hoult <·····@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
From: Dorai Sitaram
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <and15l$bjp$1@news.gte.com>
In article <···························@copper.ipg.tsnz.net>,
Bruce Hoult  <·····@hoult.org> wrote:
>In article <·················@dls.net>, "Paul F. Dietz" <·····@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.

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. 
From: Carl Shapiro
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ouyd6qt4pe9.fsf@panix3.panix.com>
····@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.
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242498491969809@naggum.no>
* 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.

-- 
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.
From: Alan S. Crowe
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <86d6qtxgsu.fsf@cawtech.freeserve.co.uk>
To: Erik Naggum <····@naggum.no>
Subject: Re: Simple newbie list processing troubble
References: <····························@posting.google.com> <·················@dls.net> <···························@copper.ipg.tsnz.net> <············@news.gte.com> <················@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
From: Will Deakin
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <anekt2$n8r$1@newsreaderm1.core.theplanet.net>
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
From: Will Deakin
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <anelav$ndq$1@newsreaderm1.core.theplanet.net>
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
From: Tim Bradshaw
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ey3adlxul5o.fsf@cley.com>
* 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
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242552231903175@naggum.no>
* 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/!

-- 
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.
From: Frode Vatvedt Fjeld
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <2h1y79gl62.fsf@vserver.cs.uit.no>
····@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
From: Vassil Nikolov
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <kzb65wlufv1.fsf@panix3.panix.com>
Frode Vatvedt Fjeld <······@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.
From: Edi Weitz
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <87ptutdrqe.fsf@bird.agharta.de>
····@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.
From: Adam Warner
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <andu5q$dgso2$1@ID-105510.news.dfncis.de>
Hi Dorai Sitaram,

> In article <···························@copper.ipg.tsnz.net>, Bruce
> Hoult  <·····@hoult.org> wrote:
>>In article <·················@dls.net>, "Paul F. Dietz" <·····@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.
> 
> 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.

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
From: Tim Bradshaw
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ey3elb9uxgx.fsf@cley.com>
* 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
From: Adam Warner
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ane9ii$d4gkp$1@ID-105510.news.dfncis.de>
Hi Tim Bradshaw,

> * 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.

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
From: Eric Marsden
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <wzi1y79tc75.fsf@melbourne.laas.fr>
>>>>> "aw" == Adam Warner <······@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/>
From: Dorai Sitaram
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <aneq6c$cr3$1@news.gte.com>
In article <··············@ID-105510.news.dfncis.de>,
Adam Warner <······@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.
From: Tim Bradshaw
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ey365wkvq14.fsf@cley.com>
* 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
From: Joe Marshall
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <y99g96wr.fsf@ccs.neu.edu>
Tim Bradshaw <···@cley.com> writes:

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

Avoiding name collisions when inlining.
From: Tim Bradshaw
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ey3ofacu81t.fsf@cley.com>
* 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
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242588716893862@naggum.no>
* 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.

-- 
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.
From: Coby Beck
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ane135$2ubd$1@otis.netspace.net.au>
"Adam Warner" <······@consulting.net.nz> wrote in message
···················@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")
From: Adam Warner
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <ane93o$dgj1m$1@ID-105510.news.dfncis.de>
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
From: Marco Antoniotti
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <y6cvg4qt4za.fsf@octagon.valis.nyu.edu>
·······@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.

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'.
From: Barry Margolin
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <07_l9.5$ln.699@paloalto-snr1.gtei.net>
In article <···············@octagon.valis.nyu.edu>,
Marco Antoniotti  <·······@cs.nyu.edu> wrote:
>
>·······@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, ······@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.
From: Michael Hudson
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <lk8z1jv6e5.fsf@pc150.maths.bris.ac.uk>
Barry Margolin <······@genuity.net> writes:
> In article <···············@octagon.valis.nyu.edu>,
> Marco Antoniotti  <·······@cs.nyu.edu> wrote:
> >·······@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
From: Marco Antoniotti
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <y6csmzr1n6n.fsf@octagon.valis.nyu.edu>
Michael Hudson <···@python.net> writes:

> Barry Margolin <······@genuity.net> writes:
> > In article <···············@octagon.valis.nyu.edu>,
> > Marco Antoniotti  <·······@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.

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'.
From: Erik Naggum
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <3242400657742787@naggum.no>
* 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.
Act from faith, and failure makes you blame someone and push harder.
From: Marco Antoniotti
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <y6c8z1j1bis.fsf@octagon.valis.nyu.edu>
Erik Naggum <····@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. 

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'.
From: Adam Warner
Subject: Re: Simple newbie list processing troubble
Date: 
Message-ID: <an42gi$aprtr$1@ID-105510.news.dfncis.de>
Hi Peder Y,

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

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