From: John Doe
Subject: accessing sets in lisp
Date: 
Message-ID: <3ad70c70.80357375@203.164.2.74>
I'm trying to write a lisp program that, when given something like :

(program `(4 5 6 (6 3 b ( 2 4 a) 5 ) c)

It will look through all the atoms individually and then print the
same thing back out to the screen..  I am having lots of troubles
trying to get it to do this. Can anyone help?

Thanks

Dan.

From: Martti Halminen
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ABA04C4.3F49780C@solibri.com>
John Doe wrote:
> 
> I'm trying to write a lisp program that, when given something like :
> 
> (program `(4 5 6 (6 3 b ( 2 4 a) 5 ) c)
> 
> It will look through all the atoms individually and then print the
> same thing back out to the screen..  I am having lots of troubles
> trying to get it to do this. Can anyone help?

Your problem statement is rather unclear. What do you mean by "look
through" and "the same thing"?

A trivial implementation of this specification (assuming you added the
missing end parenthesis) would be

(defun program (data) (print data))

Was that what you meant?

--
From: John Doe
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ad71417.82316354@203.164.2.74>
Sorry about that :)

I'm trying to write a program that, given the input :

(program `(4 5 6 (6 3 b (2 4 a) 5) c))

would look at the 4, then the 5, then the 6 and so on.  I can make it
do this as long as there are no sets within the main set (e.g (2 4 a)
in the example.).  When it comes across these, it either joins the
subset onto the main set or stops processing.

I can't get it to look at all the atoms individually, recursively..

Is this better?

Thanks

Dan.


On Thu, 22 Mar 2001 15:57:24 +0200, Martti Halminen
<···············@solibri.com> wrote:

>John Doe wrote:
>> 
>> I'm trying to write a lisp program that, when given something like :
>> 
>> (program `(4 5 6 (6 3 b ( 2 4 a) 5 ) c)
>> 
>> It will look through all the atoms individually and then print the
>> same thing back out to the screen..  I am having lots of troubles
>> trying to get it to do this. Can anyone help?
>
>Your problem statement is rather unclear. What do you mean by "look
>through" and "the same thing"?
>
>A trivial implementation of this specification (assuming you added the
>missing end parenthesis) would be
>
>(defun program (data) (print data))
>
>Was that what you meant?
>
>--
From: Martti Halminen
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ABA1199.B2FB1489@solibri.com>
John Doe wrote:

> I'm trying to write a program that, given the input :
> 
> (program `(4 5 6 (6 3 b (2 4 a) 5) c))
> 
> would look at the 4, then the 5, then the 6 and so on.  I can make it
> do this as long as there are no sets within the main set (e.g (2 4 a)
> in the example.).  When it comes across these, it either joins the
> subset onto the main set or stops processing.
> 
> I can't get it to look at all the atoms individually, recursively..
> 
> Is this better?

Not all that much. You still haven't stated what you want to happen when
your program hits an element that isn't an atom. If you want it to
recurse into the sublist, too, why not do it? You just recurse both into
the CAR and the CDR part of the list.

Why not include your program, and the output you want it to produce, in
your message, if you want more help than generalities.

P.S. Any specific reason why you are using backquote intead of quote?
P.P.S There are no sets in Lisp. A list only behaves as a set if you use
it as such, and do no operations which break the assumptions (PUSHNEW
instead of PUSH etc.)

--
From: John Doe
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ad723f6.86380110@203.164.2.74>
The code I have to traverse the list is :

(defun addone (x)
  (cond ((null x) NIL)
    (T
      (if (atom(first x))
        (if (numberp(first x))
          (cons (+ 1 (first x)) (addone (rest x)))
          (cons (first x) (addone (rest x)))
        )
      )
    )
  )
)

As you can see, it currently adds one to every atom that is a number
in the list.  I'm trying to get it to add one to every number in list
that is within the initial list.  I'm having trouble getting it to
work properly though.. 

I've  tried putting (addone (rest(first x))) at the end of the (if
atom) statement but it doesn't work still..

Thanks

Dan.

On Thu, 22 Mar 2001 16:52:09 +0200, Martti Halminen
<···············@solibri.com> wrote:

>John Doe wrote:
>
>> I'm trying to write a program that, given the input :
>> 
>> (program `(4 5 6 (6 3 b (2 4 a) 5) c))
>> 
>> would look at the 4, then the 5, then the 6 and so on.  I can make it
>> do this as long as there are no sets within the main set (e.g (2 4 a)
>> in the example.).  When it comes across these, it either joins the
>> subset onto the main set or stops processing.
>> 
>> I can't get it to look at all the atoms individually, recursively..
>> 
>> Is this better?
>
>Not all that much. You still haven't stated what you want to happen when
>your program hits an element that isn't an atom. If you want it to
>recurse into the sublist, too, why not do it? You just recurse both into
>the CAR and the CDR part of the list.
>
>Why not include your program, and the output you want it to produce, in
>your message, if you want more help than generalities.
>
>P.S. Any specific reason why you are using backquote intead of quote?
>P.P.S There are no sets in Lisp. A list only behaves as a set if you use
>it as such, and do no operations which break the assumptions (PUSHNEW
>instead of PUSH etc.)
>
>--
From: Johan Kullstam
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <m3y9txpwl9.fsf@sysengr.res.ray.com>
···@feh.com (John Doe) writes:

> The code I have to traverse the list is :
> 
> (defun addone (x)
>   (cond ((null x) NIL)
>     (T
>       (if (atom(first x))
>         (if (numberp(first x))
>           (cons (+ 1 (first x)) (addone (rest x)))
>           (cons (first x) (addone (rest x)))
>         )
>       )
>     )
>   )
> )

this is a job for MAPCAR!

(defun addone (tree)
   (mapcar #'(lambda (x)
                (cond
                  ((numberp x) (1+ x))
                  ((consp x) (addone x))
                  (t x)))
           tree))

MAPCAR is a natural if there are no embedded lists.  the consp
condition just keeps recursing on them.

> As you can see, it currently adds one to every atom that is a number
> in the list.  I'm trying to get it to add one to every number in list
> that is within the initial list.  I'm having trouble getting it to
> work properly though.. 
> 
> I've  tried putting (addone (rest(first x))) at the end of the (if
> atom) statement but it doesn't work still..
> 
> Thanks
> 
> Dan.
> 
> On Thu, 22 Mar 2001 16:52:09 +0200, Martti Halminen
> <···············@solibri.com> wrote:
> 
> >John Doe wrote:
> >
> >> I'm trying to write a program that, given the input :
> >> 
> >> (program `(4 5 6 (6 3 b (2 4 a) 5) c))
> >> 
> >> would look at the 4, then the 5, then the 6 and so on.  I can make it
> >> do this as long as there are no sets within the main set (e.g (2 4 a)
> >> in the example.).  When it comes across these, it either joins the
> >> subset onto the main set or stops processing.
> >> 
> >> I can't get it to look at all the atoms individually, recursively..
> >> 
> >> Is this better?
> >
> >Not all that much. You still haven't stated what you want to happen when
> >your program hits an element that isn't an atom. If you want it to
> >recurse into the sublist, too, why not do it? You just recurse both into
> >the CAR and the CDR part of the list.
> >
> >Why not include your program, and the output you want it to produce, in
> >your message, if you want more help than generalities.
> >
> >P.S. Any specific reason why you are using backquote intead of quote?
> >P.P.S There are no sets in Lisp. A list only behaves as a set if you use
> >it as such, and do no operations which break the assumptions (PUSHNEW
> >instead of PUSH etc.)
> >
> >--
> 

-- 
J o h a n  K u l l s t a m
[········@ne.mediaone.net]
sysengr
From: Geoff Summerhayes
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <tbkett6rqkbja8@corp.supernews.com>
"John Doe" <···@feh.com> wrote in message ······················@203.164.2.74...
> The code I have to traverse the list is :
>
> (defun addone (x)
>   (cond ((null x) NIL)
>     (T
>       (if (atom(first x))
>         (if (numberp(first x))
>           (cons (+ 1 (first x)) (addone (rest x)))
>           (cons (first x) (addone (rest x)))
>         )
>       )
>     )
>   )
> )
>
> As you can see, it currently adds one to every atom that is a number
> in the list.  I'm trying to get it to add one to every number in list
> that is within the initial list.  I'm having trouble getting it to
> work properly though..

I'm a newbie too. From the looks of what you've written, I'd say you
are used to C/C++?

What I've learned so far:

-Don't use an if when a when will do
  i.e. (if (test)(clause) nil) becomes (when (test)(clause))
-Don't use a cond when an if will do
  i.e. (cond ((test)(clause))(t (clause2))) becomes (if (test)(clause)(clause2))
-Don't use nested ifs when a cond will do

My contribution to this thread:

(defun addone (x)
   (cond ((numberp x) (+ 1 x))
         ((consp x)(cons (addone (first x))
                         (addone (rest x))))
         (t x))) ; nil is a list, but it's not a cons

Or, if you prefer typecase,

(defun addone (x)
   (typecase x
      (number (1+ x))
      (cons (cons (addone (first x))
                  (addone (rest x))))
      (t x)))

--
Geoff
From: Geoff Summerhayes
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <tbkk70rolurqaa@corp.supernews.com>
"Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> wrote in message ···················@corp.supernews.com...
>
> My contribution to this thread:
>
> (defun addone (x)
>    (cond ((numberp x) (+ 1 x))
>          ((consp x)(cons (addone (first x))
>                          (addone (rest x))))
>          (t x))) ; nil is a list, but it's not a cons
>
> Or, if you prefer typecase,
>
> (defun addone (x)
>    (typecase x
>       (number (1+ x))
>       (cons (cons (addone (first x))
>                   (addone (rest x))))
>       (t x)))

Overkill time!

(defun replace-atom (x fn &key test)
   (labels ((rplc(x)
            (cond ((endp x) '()) ; have to do null test this time
                  ((and (atom x)(or (null test)(funcall test x)))
                   (funcall fn x))
                  ((consp x)(cons (rplc (first x))
                                  (rplc (rest x))))
                  (t x))))
      (rplc x)))

CL-USER 4 > (replace-atom '(1 2 3 4) #'(lambda (x) 5))
(5 5 5 5)

CL-USER 5 > (replace-atom '(1 (2 3) 4) #'(lambda (x) (1+ x)))
(2 (3 4) 5)

CL-USER 6 > (replace-atom '(1 (2 a) 4) #'(lambda (x) (1+ x)) :test #'numberp)
(2 (3 A) 5)

There has to be a way to improve this, or is this one of those things I
just shouldn't write?

Geoff
From: Kent M Pitman
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <sfwg0g5d1hp.fsf@world.std.com>
"Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> writes:

> (defun replace-atom (x fn &key test)
>    (labels ((rplc(x)

Style point: This is a bad name for a couple of reasons.  First, through
its paucity of vowels, it looks like rplacd and rplaca; but it does not
share their side-effecting nature.  This cues the reader of your code to
make a false assumption about how you will proceed.  Second, I think you
should always try to prefer names that are English words (or at least words
in some pronounceable language); as used to be frequently repeated at
Symbolics when I worked there "there are many abbreviations for a word,
but only one right spelling"  using; that is, use the thing which is 
uniquely determined--not a poor substitute which is hard to pronounce,
easy to misspell, and easily confused with other things.  

And, by the way, most people (myself included) feel it is bad style to
not have a space between the function name and the arglist.  That is,  you
want "rplc (x)", not "rplc(x)".  The latter gives the visual cue that you
have a confusion about how function calls in Lisp are notated, and that
you still think people write f(x) instead of (f x).  Using uniform style
also means it's easier to make mechanical changes to your code, or to test
for certain uses.

>             (cond ((endp x) '()) ; have to do null test this time

I'm not sure why you're using endp here when you have an atom check in
the next clause.  You've already invited the system to signal an error
when an atom other than NIL is seen here.  ENDP is only for use in list
abstractions where you reasonably expect all lists to be null-terminated.
Here you don't even know if this is a car-side NIL or a cdr-side NIL 
when you find one, because you're recursing down the car and cdr sides
symmetrically, passing no information about which side you descended into.
That is, ENDP is only appropriate in the situation where you're recursing
differently into the cdrs (list tails) than the cars (list data).

>                   ((and (atom x)(or (null test)(funcall test x)))

Style point:  You want (not test)

NULL is for recognizing empty lists.
NOT is for recognizing false values.

NULL and NOT are, of course, computational synonyms.
But that doesn't mean you can/should use them interchangeably.

Alternatively, you could initialize test by
  &key (test (constantly t))
and then you could always assume you had a valid test.
I'm not sure that'd be faster, and it might be a touch slower, but it's
another expressive option available to you.

>                    (funcall fn x))
>                   ((consp x)(cons (rplc (first x))
>                                   (rplc (rest x))))

Style point: You want car and cdr, not first and rest.

FIRST and REST are for picking apart lists.
CAR and CDR are for picking apart conses.

If you knew you had a list, you should just do
 (mapcar #'rplc x)
The reason you aren't doing that is presumably so you can handle
improper lists, dotted pairs, or whatever you like to call them.
And for those, the REST abstraction dosn't make sense.

REST and CDR are, of course, computational synonyms.
But that doesn't mean you can/should use them interchangeably.

>                   (t x))))
>       (rplc x)))
> 
> CL-USER 4 > (replace-atom '(1 2 3 4) #'(lambda (x) 5))
> (5 5 5 5)
> 
> CL-USER 5 > (replace-atom '(1 (2 3) 4) #'(lambda (x) (1+ x)))
> (2 (3 4) 5)
> 
> CL-USER 6 > (replace-atom '(1 (2 a) 4) #'(lambda (x) (1+ x)) :test #'numberp)
> (2 (3 A) 5)
> 
> There has to be a way to improve this, or is this one of those things I
> just shouldn't write?

Are these my only two choices?
From: Geoff Summerhayes
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <tbkov1sc51jhe5@corp.supernews.com>
"Kent M Pitman" <······@world.std.com> wrote in message ····················@world.std.com...
>
> <Snipped a lot of style points>
>

Phew!

> If you knew you had a list, you should just do
>  (mapcar #'rplc x)
> The reason you aren't doing that is presumably so you can handle
> improper lists, dotted pairs, or whatever you like to call them.
> And for those, the REST abstraction dosn't make sense.

Yes, that's exactly why I did it this way. Having to deal with
the nil at the end of a list and the possibility of one inside it
was bothering me to.

Ok, how's this:

(defun replace-atom (x fn &key test)
   (labels ((replace-atom-helper (x)
               (cond ((and (atom x)(or (not test)(funcall test x)))
                       (funcall fn x))
                     ((consp x)
                        (cons (replace-atom-helper (car x))
                              (when (cdr x)
                                 (replace-atom-helper (cdr x)))))
                     (t x))))
      (replace-atom-helper x)))

Or perhaps the when should be

(if (cdr x)
   (replace-atom-helper (cdr x))
   nil)

?

> Are these my only two choices?

My fault, I should have just asked for comments. :-)

Geoff
From: Geoff Summerhayes
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <tbkq75bccdc4b9@corp.supernews.com>
"Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> wrote in message ···················@corp.supernews.com...
>
> "Kent M Pitman" <······@world.std.com> wrote in message ····················@world.std.com...
> >
> > <Snipped a lot of style points>

And I snipped too much, should have left

> > > There has to be a way to improve this, or is this one of those things I
> > > just shouldn't write?

in.

> >
> > Are these my only two choices?

Didn't realize how silly it looked until I saw it posted.

Geoff
From: Barry Margolin
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <q7qu6.55$U4.2854@burlma1-snr2>
In article <·················@203.164.2.74>, John Doe <···@feh.com> wrote:
>The code I have to traverse the list is :
>
>(defun addone (x)
>  (cond ((null x) NIL)
>    (T
>      (if (atom(first x))
>        (if (numberp(first x))
>          (cons (+ 1 (first x)) (addone (rest x)))
>          (cons (first x) (addone (rest x)))
>        )
>      )
>    )
>  )
>)
>
>As you can see, it currently adds one to every atom that is a number
>in the list.  I'm trying to get it to add one to every number in list
>that is within the initial list.  I'm having trouble getting it to
>work properly though.. 
>
>I've  tried putting (addone (rest(first x))) at the end of the (if
>atom) statement but it doesn't work still..

How about:

(defun addone (x)
  (cond ((null x) nil)
        ((numberp x) (1+ x))
        ((atom x) x)
	(t (cons (addone (car x))
                 (addone (cdr x))))))
        
-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, 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: Iban Hatchond
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ABA2282.82C3FEE5@emi.u-bordeaux.fr>
John Doe wrote:

> The code I have to traverse the list is :
>
> (defun addone (x)
>   (cond ((null x) NIL)
>     (T
>       (if (atom(first x))
>         (if (numberp(first x))
>           (cons (+ 1 (first x)) (addone (rest x)))
>           (cons (first x) (addone (rest x)))
>         )
>       )
>     )
>   )
> )
>
>

Why do use loop instead ?


(defun add-one (l)
    (loop for n in l
              if (listp n) collect (add-one n)
              else when (numberp n) collect (1+ n)))

(add-one '(1 2 3 (6 764) 4 5)) => (2 3 4 (7 765) 5 6)
(add-one '(1 2 3 (6 764) 'a 5)) => (2 3 4 (7 765) NIL 6)

Does it helps ??
From: John Doe
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <3ad733c9.90431710@203.164.2.74>
Cool.. thanks!

makes the code look at lot nicer :)

Dan.

On Thu, 22 Mar 2001 17:04:18 +0100, Iban Hatchond
<········@emi.u-bordeaux.fr> wrote:

>John Doe wrote:
>
>> The code I have to traverse the list is :
>>
>> (defun addone (x)
>>   (cond ((null x) NIL)
>>     (T
>>       (if (atom(first x))
>>         (if (numberp(first x))
>>           (cons (+ 1 (first x)) (addone (rest x)))
>>           (cons (first x) (addone (rest x)))
>>         )
>>       )
>>     )
>>   )
>> )
>>
>>
>
>Why do use loop instead ?
>
>
>(defun add-one (l)
>    (loop for n in l
>              if (listp n) collect (add-one n)
>              else when (numberp n) collect (1+ n)))
>
>(add-one '(1 2 3 (6 764) 4 5)) => (2 3 4 (7 765) 5 6)
>(add-one '(1 2 3 (6 764) 'a 5)) => (2 3 4 (7 765) NIL 6)
>
>Does it helps ??
>
>
From: Frode Vatvedt Fjeld
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <2hzoedbvl2.fsf@dslab7.cs.uit.no>
···@feh.com (John Doe) writes:

> The code I have to traverse the list is :
> 
> (defun addone (x)
>   (cond ((null x) NIL)
>     (T
>       (if (atom(first x))
>         (if (numberp(first x))
>           (cons (+ 1 (first x)) (addone (rest x)))
>           (cons (first x) (addone (rest x)))
>         )
>       )
>     )
>   )
> )

Let me suggest first of all skipping the dangling parens, and then if
what you want to do is to add one to each element in the tree:

  (defun addone (x)
    (etypecase x
      (null nil)
      (list (cons (addone (first x))
                  (addone (rest x))))
      (number (1+ x))))

If you want to add one only to elements that are numbers and just keep
other elements:

  (defun addone (x)
    (typecase x
      (null nil)
      (list (cons (addone (first x))  ; descend recursively
                  (addone (rest x))))
      (number (1+ x))                 ; add one to numbers
      (t x)))                         ; keep other objects.

I'm not sure I understand what you mean by

> I'm trying to get it to add one to every number in list that is
> within the initial list.

If you mean you only want to descend precisely one level, then that's
a (two-level) mapping problem:

  (defun addone (x)
    (mapcar #'(lambda (e)
                (if (atom e)
                    e
                  (mapcar #'(lambda (n) (if (numberp n) (1+ n) n))
                          e)))
            x))
 
-- 
Frode Vatvedt Fjeld
From: Michael Naunton
Subject: Re: accessing sets in lisp
Date: 
Message-ID: <slrn9blhj3.11f.mmn@mmn.bellatlantic.net>
(defun add1 (x) 
   (cond ((numberp x) (+ 1 x )) 
         ((listp x ) (mapcar 'add1 x )) 
         (t x )
   )
)

Probably sucky code, but it's my first lisp program in the 10 years.
-- MMN

On Thu, 22 Mar 2001 15:11:54 GMT, John Doe <···@feh.com> wrote:
>The code I have to traverse the list is :
>
>(defun addone (x)
>  (cond ((null x) NIL)
>    (T
>      (if (atom(first x))
>        (if (numberp(first x))
>          (cons (+ 1 (first x)) (addone (rest x)))
>          (cons (first x) (addone (rest x)))
>        )
>      )
>    )
>  )
>)
>
>As you can see, it currently adds one to every atom that is a number
>in the list.  I'm trying to get it to add one to every number in list
>that is within the initial list.  I'm having trouble getting it to
>work properly though.. 
>
>I've  tried putting (addone (rest(first x))) at the end of the (if
>atom) statement but it doesn't work still..
>
>Thanks
>
>Dan.
>
>On Thu, 22 Mar 2001 16:52:09 +0200, Martti Halminen
><···············@solibri.com> wrote:
>
>>John Doe wrote:
>>
>>> I'm trying to write a program that, given the input :
>>> 
>>> (program `(4 5 6 (6 3 b (2 4 a) 5) c))
>>> 
>>> would look at the 4, then the 5, then the 6 and so on.  I can make it
>>> do this as long as there are no sets within the main set (e.g (2 4 a)
>>> in the example.).  When it comes across these, it either joins the
>>> subset onto the main set or stops processing.
>>> 
>>> I can't get it to look at all the atoms individually, recursively..
>>> 
>>> Is this better?
>>
>>Not all that much. You still haven't stated what you want to happen when
>>your program hits an element that isn't an atom. If you want it to
>>recurse into the sublist, too, why not do it? You just recurse both into
>>the CAR and the CDR part of the list.
>>
>>Why not include your program, and the output you want it to produce, in
>>your message, if you want more help than generalities.
>>
>>P.S. Any specific reason why you are using backquote intead of quote?
>>P.P.S There are no sets in Lisp. A list only behaves as a set if you use
>>it as such, and do no operations which break the assumptions (PUSHNEW
>>instead of PUSH etc.)
>>
>>--
>