From: Brian D
Subject: Help on simple LISP function
Date: 
Message-ID: <th7te2jjoc5ifd@corp.supernews.com>
I need to write a function that accepts a list and produces a new list.  The
new list will keep the numeric, negative atoms at the top level and remove
everything else.  In addition it will increment these new values.  Here is
an example:
(incr-negs '(2 a 0 -4 -9 b))
    will produce
(-3 -8)

Here is the code that I have so far: (sorry for the por code, I'm new at
LISP)

(defun sum-negative (alist)
   (cond
 ((null alist) nil)
 ((minusp (car alist))(cons (car alist)
   (sum-negative (cdr alist))))

 (t (sum-negative (cdr alist)))

)
)

Any help with this would be greatly appreciated.  Thank you,
Brian.    ·······@cableone.net

From: Barry Margolin
Subject: Re: Help on simple LISP function
Date: 
Message-ID: <4hTQ6.17$F93.674@burlma1-snr2>
In article <··············@corp.supernews.com>,
Brian D <·······@cableone.net> wrote:
>I need to write a function that accepts a list and produces a new list.  The
>new list will keep the numeric, negative atoms at the top level and remove
>everything else.  In addition it will increment these new values.  Here is
>an example:
>(incr-negs '(2 a 0 -4 -9 b))
>    will produce
>(-3 -8)
>
>Here is the code that I have so far: (sorry for the por code, I'm new at
>LISP)
>
>(defun sum-negative (alist)
>   (cond
> ((null alist) nil)
> ((minusp (car alist))(cons (car alist)
>   (sum-negative (cdr alist))))
>
> (t (sum-negative (cdr alist)))
>
>)
>)
>
>Any help with this would be greatly appreciated.  Thank you,

Your basic structure is correct, there are just a few details wrong.
MINUSP requires its argument to be a number, so you have to check for this
first:

  (minusp (car alist))

should be:

  (and (numberp (car alist)) (minusp (car alist)))

The only other change you need is that you have to increment this number
when you cons it into the result, i.e.

  (cons (car alist) ...)

should be:

  (cons (1+ (car alist)) ...)

-- 
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: Frode Vatvedt Fjeld
Subject: Re: Help on simple LISP function
Date: 
Message-ID: <2hpucrapgy.fsf@dslab7.cs.uit.no>
"Brian D" <·······@cableone.net> writes:

> I need to write a function that accepts a list and produces a new
> list.  The new list will keep the numeric, negative atoms at the top
> level and remove everything else.  In addition it will increment
> these new values.

LOOP can do this.

  (loop for x in <list> when (and (numberp x) (minusp x)) collect (1+ x))

A one-liner :-)

-- 
Frode Vatvedt Fjeld
From: Kalle Olavi Niemitalo
Subject: Re: Help on simple LISP function
Date: 
Message-ID: <87g0dnga33.fsf@Astalo.y2000.kon.iki.fi>
"Brian D" <·······@cableone.net> writes:

> I need to write a function that accepts a list and produces a new list.  The
> new list will keep the numeric, negative atoms at the top level and remove
> everything else.  In addition it will increment these new values.

I think you should use the LOOP macro.  With its FOR...IN, WHEN
and COLLECT clauses, you can make the function very simple and
readable.

[reindented]
> (defun sum-negative (alist)
>   (cond
>    ((null alist) nil)
>    ((minusp (car alist)) (cons (car alist)
>                                (sum-negative (cdr alist))))
>    (t (sum-negative (cdr alist)))))

Please don't call the parameter ALIST, because that name is
normally used as an abbreviation for "association list" which
your list is not.  LIST or NUMBERS could be a good name.

A documentation string wouldn't hurt.

When your function is given an empty list, it returns nil.  It
might be better style to return '().  It's the same thing to the
compiler but a hint to human beings.

You check that the number is negative, with (MINUSP (CAR ALIST)).
The problem is that MINUSP requires a real number as an argument,
and your list can also contain other things.  So, before calling
MINUSP, you need to check that the element of the list is indeed
a real number.  You can do this with REALP.  If that returns
false, don't call MINUSP.  (You might be tempted to use NUMBERP
instead, but then your function would fail if someone gives it a
complex number.)

Then you collect the element just examined into a new list.  Here
you need to increment the value first.  Use the + operator.

Please post about your progress, especially about what is
difficult and what is easy.