From: Jeremy Medows
Subject: association list --updating
Date: 
Message-ID: <5jp6sb$s9u$1@news.nyu.edu>
Hi,
 I am pretty new to LISP and I can't seem to find the answer to this
question in any of my books.

I have the following association list:

((A.1)(B.33)(C.45)(D.9)(E.1))
How can I use the mapping functions and my function inc -- which
is just (defun inc (x) (+ x 1)) to increment each of the second values
in each dotted pair?

I would like my output to look like:
((A.2)(B.34)(C.46)(D.10)(E.2))

Jeremy

From: Lyman S. Taylor
Subject: Re: association list --updating
Date: 
Message-ID: <5jqn6s$1h7@pravda.cc.gatech.edu>
In article <············@news.nyu.edu>,
Jeremy Medows <·······@is.nyu.edu> wrote:

>I have the following association list:
>
>((A.1)(B.33)(C.45)(D.9)(E.1))
>How can I use the mapping functions and my function inc -- which
>is just (defun inc (x) (+ x 1)) to increment each of the second values
>in each dotted pair?

   Hmmm,   the function 1+ does the same thing....

		(1+ 5 ) ===> 6 

   The following with as a side effect print out each element of the 
   list each time the lambda function is invoked ( the non side effect of the
   function is to return the argument as the answer ) and result in
   a duplicate of the association list. 

? (mapcar #'(lambda (x) (print x )) '((A.1)(B.33)(C.45)(D.9)(E.1)))

(A.1) 
(B.33) 
(C.45) 
(D.9) 
(E.1) 
((A.1) (B.33) (C.45) (D.9) (E.1))

? 


  Which should be insightful enough for you to fill in the rest of the 
  desired functionality...



-- 

Lyman S. Taylor			"Because no matter where you go,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Jeremy Medows
Subject: Re: association list --updating
Date: 
Message-ID: <5jqgen$9qb$1@news.nyu.edu>
Hi, I received the answer to this.  I'd like to thank Ola Rinta-Koski.
Thanks!


Here is the answer:

(defun inc (x) (+ x 1))

(mapcar #'(lambda (x)
            (setf (cdr x) (inc (cdr x)))
              x)
        '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1)))


Here's the qustion:
: I have the following association list:
: 
: ((A.1)(B.33)(C.45)(D.9)(E.1))
: How can I use the mapping functions and my function inc -- which
: is just (defun inc (x) (+ x 1)) to increment each of the second values
: in each dotted pair?
: 
: I would like my output to look like:
: ((A.2)(B.34)(C.46)(D.10)(E.2))
: 
: Jeremy
From: Lyman S. Taylor
Subject: Re: association list --updating
Date: 
Message-ID: <5jrdl8$974@pravda.cc.gatech.edu>
In article <············@news.nyu.edu>,
Jeremy Medows <·······@is.nyu.edu> wrote:

>(defun inc (x) (+ x 1))
>
>(mapcar #'(lambda (x)
>            (setf (cdr x) (inc (cdr x)))
>              x)
>        '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1)))

  Errrr, is the intent to destructively modify the orignal list? Or 
  to produce a new association list?.  In the case of the latter,
  the above does destructive modification and doesn't produce an assoc-list. 
  In the case of the former, the above produces a list you don't want.  So 
  why create it?  You might try looking at the function MAP in that case.  
  And you might try looking up INCF while you're at it too. 
-- 

Lyman S. Taylor			"Because no matter where you go,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Marco Antoniotti
Subject: Re: association list --updating
Date: 
Message-ID: <scfvi59ede5.fsf@infiniti.PATH.Berkeley.EDU>
In article <··········@pravda.cc.gatech.edu> ·····@cc.gatech.edu (Lyman S. Taylor) writes:

   From: ·····@cc.gatech.edu (Lyman S. Taylor)
   Newsgroups: comp.lang.lisp
   Date: 25 Apr 1997 19:10:32 -0400
   Organization: College of Computing, Georgia Tech
   Path: agate!blanket.mitre.org!news.mathworks.com!gatech!smash.gatech.edu!cc.gatech.edu!lyman
   Lines: 21
   References: <············@news.nyu.edu> <············@news.nyu.edu>
   NNTP-Posting-User: lyman
   Xref: agate comp.lang.lisp:27386

   In article <············@news.nyu.edu>,
   Jeremy Medows <·······@is.nyu.edu> wrote:

   >(defun inc (x) (+ x 1))
   >
   >(mapcar #'(lambda (x)
   >            (setf (cdr x) (inc (cdr x)))
   >              x)
   >        '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1)))

     Errrr, is the intent to destructively modify the orignal list? Or 
     to produce a new association list?.  In the case of the latter,
     the above does destructive modification and doesn't produce an assoc-list. 
     In the case of the former, the above produces a list you don't want.  So 
     why create it?  You might try looking at the function MAP in that case.  
     And you might try looking up INCF while you're at it too. 


Exactly.

Destructive

(defvar *the-alist* '((k1 . a1) #| ... |# (kn . an)))

(mapcar #'(lambda (association) (incf (cdr association)) association)
        *the-alist*)

Non destructive

(mapcar #'(lambda (association)
             (cons (first association) (1+ (cdr association))))
        *the-alist*)

No type checking is done.

Cheers
-- 
Marco Antoniotti
==============================================================================
California Path Program - UCB
Richmond Field Station
tel. +1 - 510 - 231 9472
From: Duncan Smith
Subject: Re: association list --updating
Date: 
Message-ID: <33628A49.6CBB@flavors.com>
Jeremy Medows wrote:
> 
> Hi, I received the answer to this.  I'd like to thank Ola Rinta-Koski.
> Thanks!
> 
> Here is the answer:
> 
> (defun inc (x) (+ x 1))
> 
> (mapcar #'(lambda (x)
>             (setf (cdr x) (inc (cdr x)))
>               x)
>         '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1)))
> 
> Here's the qustion:
> : I have the following association list:
> :
> : ((A.1)(B.33)(C.45)(D.9)(E.1))
> : How can I use the mapping functions and my function inc -- which
> : is just (defun inc (x) (+ x 1)) to increment each of the second values
> : in each dotted pair?
> :
> : I would like my output to look like:
> : ((A.2)(B.34)(C.46)(D.10)(E.2))

Your function INC is identical to the CommonLISP function 1+.

Ordinarily one would use the macro INCF ("Increment Form").  It takes a
generalized variable or "place", such as "(cdr x)".

Note MAPCAR constructs a result list.  MAPC doesn't, it just returns its
second argument.  Use MAPC unless you need a new list.  You ARE side
affecting the original list anyway.

Try:
 (mapc #'(lambda (x) (incf (cdr x)))
     '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1))) 

or for a new list:
 (mapcar #'(lambda (x) (cons (car x) (1+ (cdr x))))
     '((A . 1)(B . 33)(C . 45)(D . 9)(E . 1))) 

-Duncan
From: Ken Tilton
Subject: Re: association list --updating
Date: 
Message-ID: <3360F23C.4EE1@bway.net>
Jeremy Medows wrote:
> 
> Hi,
>  I am pretty new to LISP and I can't seem to find the answer to this
> question in any of my books.
> 
> I have the following association list:
> 
> ((A.1)(B.33)(C.45)(D.9)(E.1))
> How can I use the mapping functions and my function inc -- which
> is just (defun inc (x) (+ x 1)) to increment each of the second values
> in each dotted pair?
> 
> I would like my output to look like:
> ((A.2)(B.34)(C.46)(D.10)(E.2))
> 
> Jeremy

You are on the right track: use a mapping function. #'mapcar is the most
famous, but it would make a *new* assoc. Since you are destructively
modifying assoc *elements*, there is no point in that (making a new list
would not leave the original unchanged), so you can use #'mapc to
iterate over the assoc (which after all is just a list). 

Have I lost you yet? <g>

Let me ask you this. Can you figure out how to *print* the second value
in each dotted pair using a mapping function?

Beside the point: see if you can find the Lisp macro that does for you
what your perfectly fine #'inc function does.

Welcome to Lisp!

Ken
From: Mark McConnell
Subject: Re: association list --updating
Date: 
Message-ID: <33616881.48B1@math.okstate.edu>
Ken Tilton wrote:
> 
> Jeremy Medows wrote:
> >
> > Hi,
> >  I am pretty new to LISP and I can't seem to find the answer to this
> > question in any of my books.
> >
> > I have the following association list:
> >
> > ((A.1)(B.33)(C.45)(D.9)(E.1))
> > How can I use the mapping functions and my function inc -- which
> > is just (defun inc (x) (+ x 1)) to increment each of the second values
> > in each dotted pair?
> >
> > I would like my output to look like:
> > ((A.2)(B.34)(C.46)(D.10)(E.2))
> >
> > Jeremy
> 
> You are on the right track: use a mapping function. #'mapcar is the most
> famous, but it would make a *new* assoc. Since you are destructively
> modifying assoc *elements*, there is no point in that (making a new list
> would not leave the original unchanged), so you can use #'mapc to
> iterate over the assoc (which after all is just a list).

Here is another way to explain it.  Say z is your association list.
When you add 1 to each number, you probably don't want to make
a whole new list; you probably just want to go into z, rip out
the 1 and replace it with a 2, rip out the 33 and replace it
with a 34, etc.  To do this:

(mapc #'(lambda (pair) (incf (cdr pair)))
      z)

Here (incf ...) takes the ..., adds 1 to it, and stores it back
_into the same location_ where it was.