• Re: Simple recursive list processing question

    From B. Pym@21:1/5 to All on Tue Jun 25 07:33:41 2024
    (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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)