Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

Time to be aggressive. Go after a tattooed Virgo.


comp / comp.lang.lisp / Re: Simple recursive list processing question

SubjectAuthor
o Re: Simple recursive list processing questionB. Pym

1
Subject: Re: Simple recursive list processing question
From: B. Pym
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Tue, 25 Jun 2024 07:33 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: No_spamming@noWhere_7073.org (B. Pym)
Newsgroups: comp.lang.lisp
Subject: Re: Simple recursive list processing question
Date: Tue, 25 Jun 2024 07:33:41 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 81
Message-ID: <v5drsj$1f2vg$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Tue, 25 Jun 2024 09:33:41 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f3516bad7bad6e8b4774a100ca8eaa7a";
logging-data="1543152"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ooQjEBW+eZF6kc8NrF8Ma"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:lkZEb93rPlTjzvB9bdKBViLIZ1s=
View all headers

> > (defun summit (a-list)
> > (if (not (null a-list))
> > (let ((x (car a-list)))
> > (if (null x)
> > (summit (cdr a-list))
> > (+ x (summit (cdr a-list)))))))
> >
> >
> > Now it doesn't enter infinite loop, however it doesn't work even
> > for the lists that doesn't contain any nil elements:
> >
> > CL-USER> (summit (list 1 2))
> >
> > And the SBCL debugger complains:
> >
> > Argument Y is not a NUMBER: NIL
> > [Condition of type SIMPLE-TYPE-ERROR]
> >
> > It seems like I'm trying to do addition using some number
> > and something that is not a number (a nil?).
> >
> > I just couldn't find how to correct it? Can somebody enlighten me?
> >
> Your second post shows that you've solved the problem, so maybe you've
> already figured this out. But notice in your solution above that the
> outer IF does not supply an explicit "else" value. The default is for IF
> to return NIL when the test fails and no "else" clause is provided. This
> is what happens when your first version reaches the end of the list:
> (summit (list 1 2))
>
> 1. Trace: (SUMMIT '(1 2))
> 2. Trace: (SUMMIT '(2))
> 3. Trace: (SUMMIT 'NIL)
> 3. Trace: SUMMIT ==> NIL
> *** - argument to + should be a number: NIL
>
> The 2nd call to SUMMIT is waiting to add 2 to the result of the 3rd
> call, which returns NIL by default.
>
> In case you're interested, here are a few ways to solve Graham's problem:
> ;;;
> ;;; Ex. 9
> ;;;
> (defun summit-1 (l)
> (apply #'+ (remove nil l)))
>
> (defun summit-2 (l)
> (reduce #'+ (remove nil l)))
>
> (defun summit-3 (l)
> (if (endp l)
> 0
> (let ((x (first l)))
> (if (null x)
> (summit-3 (rest l))
> (+ x (summit-3 (rest l)))) )))
>
> (defun summit-4 (l)
> (cond ((endp l) 0)
> ((null (first l)) (summit-4 (rest l)))
> (t (+ (first l) (summit-4 (rest l)))) ))
>
> (defun summit-5 (l)
> (loop for elt in l
> when elt
> sum elt))
>
> SUMMIT-3 is essentially the same as your second version. The last two
> are not really fair since Graham doesn't introduce COND in chapter 2,
> and he is allergic to LOOP.

Scheme:

(define (summit lst)
(do ((lst lst (cdr lst))
(sum 0 (+ sum (or (car lst) 0))))
((null? lst) sum)))

(summit '(1 #f #f 3 #f 5 7 9))
===>
25

1

rocksolid light 0.9.8
clearnet tor