Quoth [EMAIL PROTECTED] (Ludovic Courtès): > Sebastian Tennant <[EMAIL PROTECTED]> writes: >> This simple procedure behaves as expected, i.e., it provides the sum of >> a list of numbers: >> >> (define add >> (lambda (l) >> (if (null? l) >> 0 >> (+ (add (cdr l)) (car l))))) >> >> whereas this procedure results in a stack overflow: >> >> (define add >> (lambda l >> (if (null? l) >> 0 >> (+ (add (cdr l)) (car l))))) >> >> the only difference being the designation of the formal parameter of the >> anonymous procedure; l or (l). > > When creating a procedure with `(lambda args body...)', then, no matter > how it is invoked, ARGS will always be bound to the *list* of arguments > that were passed to the procedure. Consequently, such procedures can be > passed any numbers of arguments. > > Conversely, `(lambda (x) body...)' is a one-argument procedure. When it > is invoked, X is bound to its argument. > > Thus, in your case, the first `add' would be used with a single > argument, e.g., `(add '(1 2 3 4))', while the second would be used with > an indefinite number of arguments, e.g., `(add 1 2 3 4)'.
Understood... up to a point. However, I don't understand why calling the first procedure like this: (add '(1 2 3 4)) and calling the second procedure like this: (add 1 2 3 4) doesn't result in 'l' having the same value; '(1 2 3 4), in each case? To put it another way, I would expect both procedures to work provided they are called with (a) suitable argument(s). Why does the second procedure fail regardless of how it is called? > Note that none of your procedures is tail-recursive, so they consume > stack space proportional to the length of L, which can lead to a stack > overflow for large lists. A tail-recursive definition would be: > > (define add > (lambda (l) > (let loop ((l l) > (result 0)) > (if (null? l) > result > (loop (cdr l) (+ result (car l))))))) Noted. Sebastian
