* Parameters @ 2008-02-04 13:51 Sebastian Tennant 2008-02-04 14:28 ` Parameters Ludovic Courtès 0 siblings, 1 reply; 7+ messages in thread From: Sebastian Tennant @ 2008-02-04 13:51 UTC (permalink / raw) To: guile-user Hi list, No doubt something of a newbie question this... 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). Why is this? Regards, Sebastian ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 13:51 Parameters Sebastian Tennant @ 2008-02-04 14:28 ` Ludovic Courtès 2008-02-04 15:05 ` Parameters Sebastian Tennant 0 siblings, 1 reply; 7+ messages in thread From: Ludovic Courtès @ 2008-02-04 14:28 UTC (permalink / raw) To: guile-user Hi, Sebastian Tennant <sebyte@smolny.plus.com> 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)'. 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))))))) Or you can just use `+'. :-) Hope this helps, Ludovic. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 14:28 ` Parameters Ludovic Courtès @ 2008-02-04 15:05 ` Sebastian Tennant 2008-02-04 15:29 ` Parameters Chusslove Illich 2008-02-04 15:47 ` Parameters Ludovic Courtès 0 siblings, 2 replies; 7+ messages in thread From: Sebastian Tennant @ 2008-02-04 15:05 UTC (permalink / raw) To: guile-user Quoth ludo@gnu.org (Ludovic Courtès): > Sebastian Tennant <sebyte@smolny.plus.com> 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 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 15:05 ` Parameters Sebastian Tennant @ 2008-02-04 15:29 ` Chusslove Illich 2008-02-04 15:45 ` Parameters Sebastian Tennant 2008-02-04 15:47 ` Parameters Ludovic Courtès 1 sibling, 1 reply; 7+ messages in thread From: Chusslove Illich @ 2008-02-04 15:29 UTC (permalink / raw) To: guile-user [-- Attachment #1: Type: text/plain, Size: 312 bytes --] > [: Sebastian Tennant :] > Why does the second procedure fail regardless of how it is called? Because the recursive call in it is of the first type, not corresponding to the base call. You would need to use apply, i.e. (+ (apply add (cdr l)) (car l)) -- Chusslove Illich (Часлав Илић) [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 15:29 ` Parameters Chusslove Illich @ 2008-02-04 15:45 ` Sebastian Tennant 0 siblings, 0 replies; 7+ messages in thread From: Sebastian Tennant @ 2008-02-04 15:45 UTC (permalink / raw) To: guile-user Quoth Chusslove Illich <caslav.ilic@gmx.net>: >> [: Sebastian Tennant :] >> Why does the second procedure fail regardless of how it is called? > > Because the recursive call in it is of the first type, not corresponding to > the base call. Ah, of course... > You would need to use apply, i.e. > > (+ (apply add (cdr l)) (car l)) Indeed. Many thanks to all. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 15:05 ` Parameters Sebastian Tennant 2008-02-04 15:29 ` Parameters Chusslove Illich @ 2008-02-04 15:47 ` Ludovic Courtès 2008-02-04 17:22 ` Parameters Sebastian Tennant 1 sibling, 1 reply; 7+ messages in thread From: Ludovic Courtès @ 2008-02-04 15:47 UTC (permalink / raw) To: guile-user Hi, Sebastian Tennant <sebyte@smolny.plus.com> writes: > 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? L should have the same value in both cases, i.e., ((lambda l l) 1 2 3 4) => (1 2 3 4) ((lambda (l) l) '(1 2 3 4)) => (1 2 3 4) > Why does the second procedure fail regardless of how it is called? Ah, I hadn't noticed it: your second procedure should read "(apply add (cdr l))" instead of "(add (cdr l))". >> (define add >> (lambda (l) >> (let loop ((l l) >> (result 0)) >> (if (null? l) >> result >> (loop (cdr l) (+ result (car l))))))) > > Noted. Or, more elegantly: (use-modules (srfi srfi-1)) (define add (lambda (l) (fold + 0 l))) Cheers, Ludovic. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Parameters 2008-02-04 15:47 ` Parameters Ludovic Courtès @ 2008-02-04 17:22 ` Sebastian Tennant 0 siblings, 0 replies; 7+ messages in thread From: Sebastian Tennant @ 2008-02-04 17:22 UTC (permalink / raw) To: guile-user Quoth ludo@gnu.org (Ludovic Courtès): >>> (define add >>> (lambda (l) >>> (let loop ((l l) >>> (result 0)) >>> (if (null? l) >>> result >>> (loop (cdr l) (+ result (car l))))))) >> >> Noted. > > Or, more elegantly: > > (use-modules (srfi srfi-1)) > > (define add > (lambda (l) > (fold + 0 l))) Wow! More elegantly indeed! Many thanks Ludovic. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-02-04 17:22 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-02-04 13:51 Parameters Sebastian Tennant 2008-02-04 14:28 ` Parameters Ludovic Courtès 2008-02-04 15:05 ` Parameters Sebastian Tennant 2008-02-04 15:29 ` Parameters Chusslove Illich 2008-02-04 15:45 ` Parameters Sebastian Tennant 2008-02-04 15:47 ` Parameters Ludovic Courtès 2008-02-04 17:22 ` Parameters Sebastian Tennant
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).