Page 1 of 1

Is newLISP "prejudiced" against recursive function

Posted: Fri Apr 15, 2005 3:55 am
by rickyboy
Hello everyone,

Consider this function which adjoins one element 'x' to a set 'S', non-destructively.

Code: Select all

(define (adjoin1 S x)
  (if (or (= x nil) (= S nil) (member x S))
      S
      (cons x S)))
> (define L '(1 2 3))
(1 2 3)
> (adjoin1 L 0)
(0 1 2 3)
Now to adjoin more than one element (at a time), it seems natural to then say

Code: Select all

(define (adjoin S)
  (if (empty? (args))
      S
      (apply adjoin
             (cons (adjoin1 S (first (args)))
                   (rest (args))))))
but this does not work --- it fails on a 'call stack overflow'.

Now, yes, I know that the alternative definition

Code: Select all

(define (adjoin S)
  (if (empty? (args))
      S
      (let ((result S))
        (dolist (x (args))
          (set! result (adjoin1 result x))))))
works and indeed, there are other ways also, for instance:

Code: Select all

(define (adjoin S) (unique (append S (args))))
However, why doesn't the first (recursive) definition of 'adjoin' work? (I like the last definition, but I may need to define a recursive function in the future and so still need to figure out what is going on with the first definition.)

Thanks! --Ricky

Posted: Fri Apr 15, 2005 12:52 pm
by Lutz
args was not set on deeper recursion levels when empty. This is a bug which is fixed in todays development release 8.5.3 here: http://newlisp.org/downloads/development/

Lutz

ps: your first solution works now, but existing multiples of list elements will not be uniqued as in your last version, which if of course the best.

Posted: Fri Apr 15, 2005 1:10 pm
by rickyboy
Thanks Lutz!