Beginners Question - Can't manipulate a local variable

Discussion of Common Lisp
nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Beginners Question - Can't manipulate a local variable

Post by nuntius » Mon Jan 04, 2010 9:36 pm

Code: Select all

(defun add-to-list (l) (setf l ...))
In this snippet, you're passing a *value* to l and then changing its local value. Its very much like the following C++ or Java snippets.

Code: Select all

void f1(int x) { x=5; }
void f2(List l) { l=new List(); }
In lisp, it is generally considered poor form to change the value of lists which are passed as arguments, but it can be done. Just as with objects in any other language, you have to directly mutate the object's members (here the CAR and CDR of the first CONS cell).

Code: Select all

;; Good: have add-to-list return the modified list; the caller can change its variable if desired
(setf l (add-to-list l))
;; Bad: have add-to-list modify the list
(defun add-to-list (l)
  (when l
    (setf (car l) 1
          (cdr l) 2))
  l)
In C++/Java, this last version might look like

Code: Select all

List addToList(List l)
{
  if(!l.null())
  {
    l.car=1;
    l.cdr=2;
  }
  return l;
}
Why not modify lists? A decent garbage collector makes it incredibly cheap to make new lists (speed comparable to stack allocation), so there's little reason to modify the old ones. Plus the list in an argument is often a subset of a greater structure, so you have to be careful not to mess that up. Put together, there's little need and a potentially great nuisance. Some people even name functions that modify lists with an exclamation (e.g. function!), just to emphasize the danger.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Beginners Question - Can't manipulate a local variable

Post by ramarren » Mon Jan 04, 2010 11:53 pm

webguy08 wrote:How would I make it understand that I want it to change the global variable? Do I have to use defvar, or defparameter?
You use DEFPARAMETER once to declare that the variable is global and then change it. But operating on global variables directly, even if they are convenient for testing, is usually bad, for reasons which are not language specific.
webguy08 wrote:After coming from object-oriented languages this sure is very different
It is not really. You are just for some reason doing things in most weird way possible, and in any case, in addition to what nuntius said, it is exactly the same in Python:

Code: Select all

>>> gameList=['a','b','c']
>>> gameList
['a', 'b', 'c']
>>> def addToList(l):
...   l=l+['d']
...
>>> addToList(gameList)
>>> gameList
['a', 'b', 'c']
and in any language with value-passing semantics, which most 'object-oriented' languages are.

In any case, as I pointed out in the very first reply, that Lisp most certainly has objects, and you should be using them.

webguy08
Posts: 14
Joined: Sat Jan 02, 2010 4:11 pm

Re: Beginners Question - Can't manipulate a local variable

Post by webguy08 » Tue Jan 05, 2010 7:07 am

At the moment I'm just trying to get to grips with how Lisp works, before I start declaring classes and such.
It completely makes sense now after seeing the Java examples!!! In fact, I've gotten it to do what I want now :D.

Btw I really appreciate all the help guys.

Post Reply