From: Tomasz Grobelny
Subject: passing parameters by reference
Date: 
Message-ID: <ciqm72-4kp.ln1@oswiecenia.net>
Is it possible to modify a(n associative) list (specificaly: add an element)
passed to a function as parameter (and how)? Equivalent construction in C
would be passing an argument by reference. I tried nsubstitute and it
modifies the list, delete properly deletes elements but I found no function
to add an element. I also tried using setf and setq but they seem to have
no effect (or operate on local copy). TIA

Tomasz Grobelny

From: Cameron MacKinnon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <jpKdnV-CeKhZXTXcRVn-jA@golden.net>
Tomasz Grobelny wrote:
> Is it possible to modify a(n associative) list (specificaly: add an element)
> passed to a function as parameter (and how)? Equivalent construction in C
> would be passing an argument by reference. I tried nsubstitute and it
> modifies the list, delete properly deletes elements but I found no function
> to add an element. I also tried using setf and setq but they seem to have
> no effect (or operate on local copy). TIA

(defun frob (x) (setf (cdr x) (cons 'a (cdr x))))

(let ((thislist (list 'w 'x 'y 'z)))
   (frob thislist)
   thislist) => (W A X Y Z)
From: Frank Buss
Subject: Re: passing parameters by reference
Date: 
Message-ID: <coaeg0$h1q$3@newsreader2.netcologne.de>
Tomasz Grobelny <·····@poczta.onet.pl> wrote:

> Is it possible to modify a(n associative) list (specificaly: add an
> element) passed to a function as parameter (and how)? 

yes, use nconc.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Kenny Tilton
Subject: Re: passing parameters by reference
Date: 
Message-ID: <us3qd.32173$Vk6.4989@twister.nyc.rr.com>
Tomasz Grobelny wrote:

> Is it possible to modify a(n associative) list (specificaly: add an element)
> passed to a function as parameter (and how)? Equivalent construction in C
> would be passing an argument by reference. I tried nsubstitute and it
> modifies the list, delete properly deletes elements but I found no function
> to add an element. I also tried using setf and setq but they seem to have
> no effect (or operate on local copy). TIA

You really should post the code with which you are playing and say "here 
  is the code. i wanted it to do this. it does this instead." if you 
really want to go crazy, show the C code.

meanwhile, two things: re "have no effect (or operate on local copy)", 
yes, you will have to 9a) return the modified list and (b) capture it in 
the caller. You cannot do the C thing and pass a variable by reference 
and have the called function modify the variable in the caller. But that 
comes up in C mostly when the function already returns some useful 
result and you want a second result as well, so you pass a variable by 
reference so the calle can write to it.

in Lisp, we say (values main-result ancillary-result) in the callee, 
then in the caller: (multiple-value-bind (m a) (callee 1 2 3)
                       ...<do what you will with m and a>)

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Tomasz Grobelny
Subject: Re: passing parameters by reference
Date: 
Message-ID: <mtin72-mjk.ln1@oswiecenia.net>
Kenny Tilton wrote:

> 
> 
> Tomasz Grobelny wrote:
> 
>> Is it possible to modify a(n associative) list (specificaly: add an
>> element) passed to a function as parameter (and how)? Equivalent
>> construction in C would be passing an argument by reference. I tried
>> nsubstitute and it modifies the list, delete properly deletes elements
>> but I found no function to add an element. I also tried using setf and
>> setq but they seem to have no effect (or operate on local copy). TIA
> 
> You really should post the code with which you are playing and say "here
>   is the code. i wanted it to do this. it does this instead." if you
> really want to go crazy, show the C code.
> 
Ok, here it is:
;;I've got a function defined like this:
> (defun add (_list _element) (setf _list (cons _element _list)))
;;and a list
> (setf qaz '(b c d e f))
;;now I want to modify the list:
> (add qaz 'a) => (A B C D E F)
;;but qaz is unchanged:
> qaz => (B C D E F)

> meanwhile, two things: re "have no effect (or operate on local copy)",
> yes, you will have to 9a) return the modified list and (b) capture it in
> the caller.
I would do it that way if it wasn't said explicitely in my homework
description that the list has to be modified.

Tomek
From: David Sletten
Subject: Re: passing parameters by reference
Date: 
Message-ID: <R7aqd.17211$Uj.9169@twister.socal.rr.com>
Tomasz Grobelny wrote:

> 
>>(defun add (_list _element) (setf _list (cons _element _list)))
> 
> ;;and a list
> 
>>(setf qaz '(b c d e f))
> 
> ;;now I want to modify the list:
> 
>>(add qaz 'a) => (A B C D E F)
> 
> ;;but qaz is unchanged:
> 
>>qaz => (B C D E F)
> 
> 

There are a couple of things you seem to be missing:
1. Common Lisp has different namespaces for, inter alia, variables and 
functions. What this means is that while the symbol LIST names a 
built-in function, it can also be used independently as a variable name 
too: (defun add (list element) ...

2. Within the body of your function ADD, the variable LIST serves as an 
alias to the argument passed to the function:

LIST ->
QAZ  -> [*|*]--->[*|*]--->[*|*]--->[*|*]--->[*|*]--->NIL
          |        |        |        |        |
          v        v        v        v        v
          B        C        D        E        F

As you discovered, when you perform the SETF in ADD you are only 
changing (in this case) the value of LIST, not QAZ:
LIST -> [*|*]
          | |
          v |
          A |
            v
QAZ  ->   [*|*]--->[*|*]--->[*|*]--->[*|*]--->[*|*]--->NIL
            |        |        |        |        |
            v        v        v        v        v
            B        C        D        E        F

In order to modify QAZ, you have to modify its referent. Here's one way 
to do that:
(defun add-to-alist (pair a-list)
   (psetf (car a-list) pair
          (cdr a-list) (cons (car a-list) (cdr a-list))))

(defvar *a* (pairlis '(a b c) '(1 2 3)))
(add-to-alist (cons 'd 4) *a*) => NIL
*a* => ((D . 4) (C . 3) (B . 2) (A . 1))

ADD-TO-ALIST suffers from the same problem Peter pointed out--it doesn't 
work if A-LIST is (). You should also note the care others used in their 
examples to avoid modifying literal values.

> 
> I would do it that way if it wasn't said explicitely in my homework
> description that the list has to be modified.
> 
It's good to see you're honest about your homework. Chris's version 
looks like the best solution as long as you don't literally have to use 
a function.

David Sletten
From: Surendra Singhi
Subject: using function names as variable names? Justified?
Date: 
Message-ID: <cobc91$j2l$1@news.asu.edu>
Taken from thread Re: passing parameters by reference
David Sletten wrote:
> There are a couple of things you seem to be missing:
> 1. Common Lisp has different namespaces for, inter alia, variables and 
> functions. What this means is that while the symbol LIST names a 
> built-in function, it can also be used independently as a variable name 
> too: (defun add (list element) ...

I have seen a couple of discussions on this earlier, but don't you feel 
it is confusing and error prone to use such names as variables. 
Especially when someone is looking at a piece of code cursorily the 
variable may look like a function call, particularily with let expressions.
Example:
(defun add()
    (let ((var (list exp))
          (list (cons a b))
           .....
or some piece of line in a long function:
    (list list abc)

I agree that a careful look at the code will definitely reveal whether 
it is a function call or a variable name, but is it worth doing?
And as a principle of clean programming practice shouldn't it be 
discouraged?


-- 
Surendra Singhi

www.public.asu.edu/~sksinghi
From: Christopher C. Stacy
Subject: Re: using function names as variable names? Justified?
Date: 
Message-ID: <ur7mera1c.fsf@news.dtpq.com>
Surendra Singhi <·········@netscape.net> writes:
> don't you feel it is confusing and error prone to use 
> such names as variables.

Absolutely not.  Never been confused by it nor made an error about it.
(Never heard of anyone else who did, either.)
From: Kenny Tilton
Subject: Re: using function names as variable names? Justified?
Date: 
Message-ID: <aPbqd.32624$Vk6.24886@twister.nyc.rr.com>
Surendra Singhi wrote:

> Taken from thread Re: passing parameters by reference
> David Sletten wrote:
> 
>> There are a couple of things you seem to be missing:
>> 1. Common Lisp has different namespaces for, inter alia, variables and 
>> functions. What this means is that while the symbol LIST names a 
>> built-in function, it can also be used independently as a variable 
>> name too: (defun add (list element) ...
> 
> 
> I have seen a couple of discussions on this earlier, but don't you feel 
> it is confusing and error prone to use such names as variables. 
> Especially when someone is looking at a piece of code cursorily the 
> variable may look like a function call, particularily with let expressions.
> Example:
> (defun add()
>    (let ((var (list exp))
>          (list (cons a b))

i am up to about three compiler warnings so far... :)

>           .....
> or some piece of line in a long function:
>    (list list abc)
> 
> I agree that a careful look at the code will definitely reveal whether 
> it is a function call or a variable name, but is it worth doing?
> And as a principle of clean programming practice shouldn't it be 
> discouraged?

Well, the big answer is that the highly regular syntax of Lisp includes 
the big win of making these things less ambiguous. Which reminds me of 
the superbig answer, which is, forget it, code is never readable.

The small answer is that there is almost always a better name than 
"list". Folks who code:

(defun add (a b &aux (list (list a b)))
    (apply '+ list))

...um, should have used "addends" instead of "list".

Unless one is writing a pure list-munching utility, in which case I 
cannot think of a better name for the list argument than list.

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Kenny Tilton
Subject: Re: passing parameters by reference
Date: 
Message-ID: <dvaqd.32608$Vk6.21859@twister.nyc.rr.com>
Tomasz Grobelny wrote:
> Kenny Tilton wrote:
> 
> 
>>
>>Tomasz Grobelny wrote:
>>
>>
>>>Is it possible to modify a(n associative) list (specificaly: add an
>>>element) passed to a function as parameter (and how)? Equivalent
>>>construction in C would be passing an argument by reference. I tried
>>>nsubstitute and it modifies the list, delete properly deletes elements
>>>but I found no function to add an element. I also tried using setf and
>>>setq but they seem to have no effect (or operate on local copy). TIA
>>
>>You really should post the code with which you are playing and say "here
>>  is the code. i wanted it to do this. it does this instead." if you
>>really want to go crazy, show the C code.
>>
> 
> Ok, here it is:
> ;;I've got a function defined like this:
> 
>>(defun add (_list _element) (setf _list (cons _element _list)))
> 
> ;;and a list
> 
>>(setf qaz '(b c d e f))
> 
> ;;now I want to modify the list:
> 
>>(add qaz 'a) => (A B C D E F)
> 
> ;;but qaz is unchanged:
> 
>>qaz => (B C D E F)
> 
> 
>>meanwhile, two things: re "have no effect (or operate on local copy)",
>>yes, you will have to 9a) return the modified list and (b) capture it in
>>the caller.
> 
> I would do it that way if it wasn't said explicitely in my homework
> description that the list has to be modified.

The short answer is, no, this cannot be done. And maybe the homework is 
meant as an exercise in frustration until you convince yourself it 
cannot be done, learning a lot along the way.

Even a destructive function's result must be captured:

    (setf qaz (add qaz 'a))

Some have suggested using a macro. That would work, but only by 
expanding into the above. In fact, the above is the expansion of the 
PUSH macro. If the goal of the homework was to discover macros, yer done.

Others have suggested appending to the end, but that does not work on an 
empty list (as further others have pointed out).

kenny


If the list you are passing is empty, aka nil, there is nothing


-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Pascal Bourguignon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <87is7qg0wx.fsf@thalassa.informatimago.com>
Kenny Tilton <·······@nyc.rr.com> writes:
> >>Tomasz Grobelny wrote:
> >>>Is it possible to modify a(n associative) list (specificaly: add an
> >>>element) passed to a function as parameter (and how)? Equivalent
> >>>construction in C would be passing an argument by reference. I tried
> >>>nsubstitute and it modifies the list, delete properly deletes elements
> >>>but I found no function to add an element. I also tried using setf and
> >>>setq but they seem to have no effect (or operate on local copy). TIA
> [...]
> The short answer is, no, this cannot be done. And maybe the homework
> is meant as an exercise in frustration until you convince yourself it
> cannot be done, learning a lot along the way.
> 
> Even a destructive function's result must be captured:
> 
>     (setf qaz (add qaz 'a))
> 
> Some have suggested using a macro. That would work, but only by
> expanding into the above. In fact, the above is the expansion of the
> PUSH macro. If the goal of the homework was to discover macros, yer
> done.
> 
> Others have suggested appending to the end, but that does not work on
> an empty list (as further others have pointed out).

However, there is something that approach the references of C in
lisp. It works only on dynamic (special) variables. This is call-by-name:

(defparameter *var1* nil)
(defparameter *var2* (list '(:a . 1)))

(defun add-acons (name key value)
    (set name (cons (cons key value) (eval name)))) ; <====  ;-) !

(add-acons '*var1* :one "Uno")
(add-acons '*var2* :b   2) 

(list *var1* *var2*)   ---> (((:ONE . "Uno")) ((:B . 2) (:A . 1)))

and:

(progn (print *var1*) 
       (let ((*var1* '((:lex . t)))) 
          (add-acons '*var1* :modified "the lexical one") (print *var1*))
       (print *var1*))

prints as expected:

    ((:ONE . "Uno")) 
    ((:MODIFIED . "the lexical one") (:LEX . T)) 
    ((:ONE . "Uno")) 



(better use define-modify-macro)

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.
From: Chris Capel
Subject: Re: passing parameters by reference
Date: 
Message-ID: <10qigjp9gn8sg0b@corp.supernews.com>
Pascal Bourguignon wrote:

> However, there is something that approach the references of C in
> lisp. It works only on dynamic (special) variables. This is call-by-name:

Cool! I should have thought of this before. I wonder if there's a way to
make it work for lexical variables.

> (defparameter *var1* nil)
> (defparameter *var2* (list '(:a . 1)))
> 
> (defun add-acons (name key value)
>     (set name (cons (cons key value) (eval name)))) ; <====  ;-) !

What about

(defun add-acons (name key value)
  (set name (cons (cons key value) (symbol-value name))))
                                    ^^^^^^^^^^^^

Chris Capel
From: Peter Seibel
Subject: Re: passing parameters by reference
Date: 
Message-ID: <m31xeer516.fsf@javamonkey.com>
Chris Capel <······@iba.nktech.net> writes:

> Pascal Bourguignon wrote:
>
>> However, there is something that approach the references of C in
>> lisp. It works only on dynamic (special) variables. This is call-by-name:
>
> Cool! I should have thought of this before. I wonder if there's a
> way to make it work for lexical variables.

Nope. The names of lexical variables are long gone by the time the
code runs. However you can do this:

  (defmacro reference (name) 
    (let ((value (gensym))
          (value-supplied-p (gensym)))
      `#'(lambda (&optional (,value nil ,value-supplied-p))
           (when ,value-supplied-p (setf ,name ,value))
           ,name)))

  (defun (setf dereference) (value reference)
    (funcall reference value))

  (defun dereference (reference)
    (funcall reference))

  (defun add-acons (key value reference)
    (push (cons key value) (dereference reference)))

  (defun foo ()
    (let ((x ()))
      (acons/reference 'key 'value (reference x))
      (acons/reference 'key2 'value2 (reference x))
      x))

  (foo) ==> ((KEY2 . VALUE2) (KEY . VALUE))

But that's just silly.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: passing parameters by reference
Date: 
Message-ID: <bFbqd.32621$Vk6.30104@twister.nyc.rr.com>
Pascal Bourguignon wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
>>>>Tomasz Grobelny wrote:
>>>>
>>>>>Is it possible to modify a(n associative) list (specificaly: add an
>>>>>element) passed to a function as parameter (and how)? Equivalent
>>>>>construction in C would be passing an argument by reference. I tried
>>>>>nsubstitute and it modifies the list, delete properly deletes elements
>>>>>but I found no function to add an element. I also tried using setf and
>>>>>setq but they seem to have no effect (or operate on local copy). TIA
>>
>>[...]
>>The short answer is, no, this cannot be done. And maybe the homework
>>is meant as an exercise in frustration until you convince yourself it
>>cannot be done, learning a lot along the way.
>>
>>Even a destructive function's result must be captured:
>>
>>    (setf qaz (add qaz 'a))
>>
>>Some have suggested using a macro. That would work, but only by
>>expanding into the above. In fact, the above is the expansion of the
>>PUSH macro. If the goal of the homework was to discover macros, yer
>>done.
>>
>>Others have suggested appending to the end, but that does not work on
>>an empty list (as further others have pointed out).
> 
> 
> However, there is something that approach the references of C in
> lisp. It works only on dynamic (special) variables. This is call-by-name:
> 
> (defparameter *var1* nil)
> (defparameter *var2* (list '(:a . 1)))
> 
> (defun add-acons (name key value)
>     (set name (cons (cons key value) (eval name)))) ; <====  ;-) !
> 
> (add-acons '*var1* :one "Uno")

Nonsense! This approaches C's ability to pass the address of a local 
variable?! You are not even passing the special variable *var*!!!! You 
are passing the symbol '*var*!!!!!!!! That is a data structure!!!!!! 
Everyone knows a data structure can be mutated by the callee!!!!!!!! And 
this is a beginner homework question!?!??!?!?!?!?!!!!?!?!!!11!! Answered 
using EVAL??????????????

:)

kenny

-- 
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Szymon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <87d5xzrv7v.fsf@eva.rplacd.net>
Tomasz Grobelny <·····@poczta.onet.pl> writes:

> Is it possible to modify a(n associative) list (specificaly: add an element)
> passed to a function as parameter (and how)? Equivalent construction in C
> would be passing an argument by reference. I tried nsubstitute and it
> modifies the list, delete properly deletes elements but I found no function
> to add an element. I also tried using setf and setq but they seem to have
> no effect (or operate on local copy). TIA
> 
> Tomasz Grobelny

(defun ass-destructive (ass new-acons)
  (rplacd (last ass) (list new-acons))
  (values))


CL-USER> (defparameter a1 (list (cons 'a 1) (cons 'b 2)))
A1

CL-USER> a1
((A . 1) (B . 2))

CL-USER> (ass-destructive a1 (cons 'c 3))
; No value

CL-USER> a1
((A . 1) (B . 2) (C . 3))


HTH, Szymon.
From: Cameron MacKinnon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <2uSdnVoxEfTUUTXcRVn-hA@golden.net>
Szymon wrote:
> (defun ass-destructive (ass new-acons)
>   (rplacd (last ass) (list new-acons))
>   (values))

Lists with O(n) insertion are deprecated by the Kyoto Global Warming Treaty.
From: Szymon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <87vfbrhycc.fsf@eva.rplacd.net>
Cameron MacKinnon <··········@clearspot.net> writes:

> Szymon wrote:
> > (defun ass-destructive (ass new-acons)
> >   (rplacd (last ass) (list new-acons))
> >   (values))
> 
> Lists with O(n) insertion are deprecated by the Kyoto Global Warming Treaty.

LOL.

Can I put this in my sig?

Regards, Szymon.
From: Peter Seibel
Subject: Re: passing parameters by reference
Date: 
Message-ID: <m3k6s7gldm.fsf@javamonkey.com>
Szymon <············@o2.pl> writes:

> Tomasz Grobelny <·····@poczta.onet.pl> writes:
>
>> Is it possible to modify a(n associative) list (specificaly: add an
>> element) passed to a function as parameter (and how)? Equivalent
>> construction in C would be passing an argument by reference. I
>> tried nsubstitute and it modifies the list, delete properly deletes
>> elements but I found no function to add an element. I also tried
>> using setf and setq but they seem to have no effect (or operate on
>> local copy). TIA
>> 
>> Tomasz Grobelny
>
> (defun ass-destructive (ass new-acons)
>   (rplacd (last ass) (list new-acons))
>   (values))
>
>
> CL-USER> (defparameter a1 (list (cons 'a 1) (cons 'b 2)))
> A1
>
> CL-USER> a1
> ((A . 1) (B . 2))
>
> CL-USER> (ass-destructive a1 (cons 'c 3))
> ; No value
>
> CL-USER> a1
> ((A . 1) (B . 2) (C . 3))


  CL-USER> (defparameter *ass* nil)
  *ASS*
  CL-USER> (ass-destructive *ass* (cons 'a 1))
  Attempt to store in the cdr field of NIL which is not a cons.
     [Condition of type TYPE-ERROR]

  Restarts:
    0: [ABORT] Abort handling SLIME request.
    1: [ABORT] Abort entirely from this (lisp) process.


Ooops. This is, as Kenny would say, a Sign From The Gods that this is
not really what you want to do.

The OP should also note that DELETE doesn't necessarily work the way
he expects:

  CL-USER> (defparameter *x* (list (cons 'a 1)))
  *X*
  CL-USER> *x*
  ((A . 1))
  CL-USER> (delete (assoc 'a *x*) *x*)
  NIL
  CL-USER> *x*
  ((A . 1))

The thing here is most of the "destructive" list operators are
intended to be used as replacements for their non-destructive
counterparts as an optimization when you know it's okay to "recycle"
the cons cells that make up the argument. How exactly they modify the
list structure is often left open and in cases like the two I just
demonstrated, *can't* do what folks sometimes expect them to do. For
more of my thoughts on this topic see:

  <http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html>

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Szymon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <87r7mfhy2k.fsf@eva.rplacd.net>
Peter Seibel <·····@javamonkey.com> writes:

> The thing here is most of the "destructive" list operators are
> intended to be used as replacements for their non-destructive
> counterparts as an optimization when you know it's okay to "recycle"
> the cons cells that make up the argument. How exactly they modify the
> list structure is often left open and in cases like the two I just
> demonstrated, *can't* do what folks sometimes expect them to do. For
> more of my thoughts on this topic see:
> 
>   <http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html>

Thank you.

Regards, Szymon.

ps. http://lisp.jogger.pl/comment.php?eid=75827&startid=0
From: Szymon
Subject: Re: passing parameters by reference
Date: 
Message-ID: <878y8nru6u.fsf@eva.rplacd.net>
Szymon <············@o2.pl> writes:

> Tomasz Grobelny <·····@poczta.onet.pl> writes:
> 
> > Is it possible to modify a(n associative) list (specificaly: add an
> > element) passed to a function as parameter (and how)? Equivalent
> > construction in C would be passing an argument by reference. I tried
> > nsubstitute and it modifies the list, delete properly deletes elements
> > but I found no function to add an element. I also tried using setf and
> > setq but they seem to have no effect (or operate on local copy). TIA
> > 
> > Tomasz Grobelny
> 
> (defun ass-destructive (ass new-acons)
>   (rplacd (last ass) (list new-acons))
>   (values))
> 
> 
> CL-USER> (defparameter a1 (list (cons 'a 1) (cons 'b 2)))
> A1
> 
> CL-USER> a1
> ((A . 1) (B . 2))
> 
> CL-USER> (ass-destructive a1 (cons 'c 3))
> ; No value
> 
> CL-USER> a1
> ((A . 1) (B . 2) (C . 3))
> 
> 
> HTH, Szymon.

Btw,

CL-USER> (defparameter a1 (list '(:dummy) (cons 'a 1) (cons 'b 2)))
A1

CL-USER> (ass-first a1 (cons 'c 3))
; No value

CL-USER> a1
((:DUMMY) (C . 3) (A . 1) (B . 2))

CL-USER> (ass-first a1 (cons 'd 4))
; No value

CL-USER> a1
((:DUMMY) (D . 4) (C . 3) (A . 1) (B . 2))

(defun ass-first (ass new-acons)
  (rplacd ass (cons new-acons (cdr ass)))
  (values))

Regards, Szymon.
From: Pascal Costanza
Subject: Re: passing parameters by reference
Date: 
Message-ID: <coajo0$2k2$1@newsreader2.netcologne.de>
Tomasz Grobelny wrote:
> Is it possible to modify a(n associative) list (specificaly: add an element)
> passed to a function as parameter (and how)? Equivalent construction in C
> would be passing an argument by reference. I tried nsubstitute and it
> modifies the list, delete properly deletes elements but I found no function
> to add an element. I also tried using setf and setq but they seem to have
> no effect (or operate on local copy).

I would do this as a macro, so you are safe even when your original list 
is empty. (The other suggestions that hint towards nconc are dangerous 
in that regard.)

Specifically, Common Lisp provides a way to concisely define such 
modification macros:

(define-modify-macro aconsf (key value)
   (lambda (alist key value)
     (acons key value alist)))

Now you can say: (aconsf reference key value) [note: untested]


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Kalle Olavi Niemitalo
Subject: Re: passing parameters by reference
Date: 
Message-ID: <87d5xzm2k0.fsf@Astalo.kon.iki.fi>
Pascal Costanza <········@web.de> writes:

> (define-modify-macro aconsf (key value)
>    (lambda (alist key value)
>      (acons key value alist)))

That is not portable: the third argument of DEFINE-MODIFY-MACRO
is specified to be a symbol, not a lambda expression (nor even
a setf function name).

Incidentally, the same applies to the SATISFIES type specifier.
From: Pascal Costanza
Subject: Re: passing parameters by reference
Date: 
Message-ID: <cob2op$qjm$1@newsreader2.netcologne.de>
Kalle Olavi Niemitalo wrote:
> Pascal Costanza <········@web.de> writes:
> 
>>(define-modify-macro aconsf (key value)
>>   (lambda (alist key value)
>>     (acons key value alist)))
> 
> That is not portable: the third argument of DEFINE-MODIFY-MACRO
> is specified to be a symbol, not a lambda expression (nor even
> a setf function name).

You're right, but that's easy to fix.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Christopher C. Stacy
Subject: Re: passing parameters by reference
Date: 
Message-ID: <uzn12j43l.fsf@news.dtpq.com>
Tomasz Grobelny <·····@poczta.onet.pl> writes:
> Is it possible to modify a(n associative) list (specificaly: add an
> element) passed to a function as parameter (and how)?

There are two answers to your question.

1. Try thinking of it this way: everything in Lisp is passed 
   by reference, except that you never de-reference anything.

If you passed in an array, any changes you make to array elements 
is seen globally by anyone who has a pointer to the array.  
But in Lisp we would never say "pointer to"; we would just 
say "passed the array" or "function YYY also has the array".

Passing in a list means passing in a reference to the head 
of the list.  The caller might have a pointer to some other
part of the list, so you can only make changes on the parts
that you share.  For example, you can't add something to the
beginning of the list. But you can splice things into the 
middle of the list, or at the end.

(defun foo ()
  (let ((x (list 1 2 3 4)))
    (bar (rest x))
    (reduce #'+ x)))
        

(defun bar (list)
  (setf (elt list 1) 42) ;; Change 3 to 42.
  (setf list nil))       ;; Pointless and does not affect caller.

(foo) -> 49

You mentioned the DELETE function.  Carefully read the documentation
for DELETE, and see that it does not necessarily modify its argument.
You are supposed to use its return value.

2. Besides functions, Lisp also has forms that obey different 
evaluation rules.  For example, the SETQ and SETQ operators
are not functions, and calling them doesn't work the same
way as I described above.   In particular, those two forms
do not evaluate their first argument.  Rather, the first
argument is a piece of Lisp code, and rather than that
argument being evaluated, they run an analysis on it to
decide what to do with the rest of the arguments.
SETQ expects its first argument to be a symbol, and the 
second argument is a value.  It considers te symbol to 
name a variable, and assigns the value.  (The value is
processed using the normal evaluation rules like a
function call would have done).

Users can invent their own arbitrary forms like that
these are called "macros".  A macro call looks syntactically
much like a function call, but of course it's really just
plugging some code into its caller.   So, for example,
a macro could receive the name of a variable that is
in the caller's scope.  When the macro is "expanded",
it produces some code that uses that variable name.
This code occurs in the caller's scope.

So, for example.

(defmacro tweak (list-var new-head)
 `(setq ,list-var (cons ,new-head ,list-var)))

(defun foo ()
  (let ((x (list 1 2 3 4)))
    (tweak x 'abcd)
    (first x)))

(foo) => ABCD


cheers,
Chris
From: Brian Downing
Subject: Re: passing parameters by reference
Date: 
Message-ID: <DZfqd.575938$mD.331577@attbi_s02>
In article <··············@oswiecenia.net>,
Tomasz Grobelny  <·····@poczta.onet.pl> wrote:
> Is it possible to modify a(n associative) list (specificaly: add an
> element) passed to a function as parameter (and how)? Equivalent
> construction in C would be passing an argument by reference. I tried
> nsubstitute and it modifies the list, delete properly deletes elements
> but I found no function to add an element. I also tried using setf and
> setq but they seem to have no effect (or operate on local copy). TIA

Here is an alternate path that you may want to think about.  In most
cases this is not going to be recommended over some of the other
solutions presented here, but it is easily possible in CL.

It is quite easy to define a macro MAKE-REFERENCE, and functions
DEREFERENCE and (SETF DEREFERENCE) to allow something like the & and *
operators in C for Lisp lexical variables.  This allows code like:

(defun add-to-list-ref (value ref)
  (format t "adding ~A to ~A" value (dereference ref))
  (push value (dereference ref)))

CL-USER> (let ((a nil))
           (add-to-list-ref 'new (make-reference a))
           a)
adding NEW to NIL
(NEW)

Since this is homework, think about how you could implement these.  :)

(As a hint, think about how closures let you capture the lexical
environment.)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Brian Downing
Subject: Re: passing parameters by reference
Date: 
Message-ID: <A6gqd.575954$mD.241405@attbi_s02>
In article <······················@attbi_s02>,
Brian Downing  <·············@lavos.net> wrote:
> It is quite easy to define a macro MAKE-REFERENCE, and functions
> DEREFERENCE and (SETF DEREFERENCE) to allow something like the & and *
> operators in C for Lisp lexical variables.
> 
> Since this is homework, think about how you could implement these.  :)

Er, Peter already posted a similar implementation.  That's what I get
for not reading the thread before chiming in.  :)

As he said, it's a bit silly to actually use in most cases, but I think
it's a good excercise anyway.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Kalle Olavi Niemitalo
Subject: Re: passing parameters by reference
Date: 
Message-ID: <873byumi8h.fsf@Astalo.kon.iki.fi>
Brian Downing <·············@lavos.net> writes:

> It is quite easy to define a macro MAKE-REFERENCE, and functions
> DEREFERENCE and (SETF DEREFERENCE) to allow something like the & and *
> operators in C for Lisp lexical variables.

However, it is currently not possible to generalize that to
places with an arbitrary number of values so that

  (setf (dereference ref)
        (values-list (nreverse (multiple-value-list (dereference ref)))))

does the right thing, because SETF wants to know the number of
store variables at macroexpand time.  The MAKE-REFERENCE side is
not a problem.

This could be solved by extending the concept of setf expansions
so that the list of store variables can be dotted.  A similar
change in MULTIPLE-VALUE-BIND would then be convenient, too.
Using &REST would be more stylish, but might break programs that
MULTIPLE-VALUE-BIND &REST as a lexical variable.

In the meantime, the best you can do with multi-valued references
is to indicate the number of values as in (dereference ref 3).