Try something simpler to see how this works. For example, here's a version of a list-sum function that receives a continuation argument (which is often called k ): (define (list-sum l k) (if (null? L)?(list-sum (cdr l)?))) The basic pattern is there, and the missing parts are where the interesting things happen.
The continuation argument is a function that expects to receive the result -- so if the list is null, it's clear that we should send it 0 since that is the sum: (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l)?))) Now, when the list is not null, we call the function recursively with the list's tail (in other words, this is an iteration), but the question is what should the continuation be. Doing this: (define (list-sum l k) (if (null?
L) (k 0) (list-sum (cdr l) k))) is clearly wrong -- it means that k will eventually receive the the sum of (cdr l) instead of all of l Instead, use a new function there, which will sum up the first element of l too along with the value that it receives: (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l) (lambda (sum) (+ (car l) sum))))) This is getting closer, but still wrong. But it's a good point to think about how things are working -- we're calling list-sum with a continuation that will itself receive the overall sum, and add the first item we see now to it.
The missing part is evident in the fact that we're ignoring k What we need is to compose k with this function -- so we do the same sum operation, then send the result to k : (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l) (compose k (lambda (s) (+ s (car l))))))) which is finally working. (BTW, remember that each of these lambda functions has its own "copy" of l ) You can try this with: (list-sum '(1 2 3 4) (lambda (x) x)) And finally note that this is the same as: (define (list-sum l k) (if (null?
L) (k 0) (list-sum (cdr l) (lambda (s) (k (+ s (car l))))))) if you make the composition explicit (You can also use this code in the intermediate+lambda student language, and click the stepper button to see how the evaluation proceeds -- this will take a while to go over, but you'll see how the continuation functions get nested, each with it's own view of the list.).
Try something simpler to see how this works. For example, here's a version of a list-sum function that receives a continuation argument (which is often called k): (define (list-sum l k) (if (null? L)?(list-sum (cdr l)?))) The basic pattern is there, and the missing parts are where the interesting things happen.
The continuation argument is a function that expects to receive the result -- so if the list is null, it's clear that we should send it 0, since that is the sum: (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l)?))) Now, when the list is not null, we call the function recursively with the list's tail (in other words, this is an iteration), but the question is what should the continuation be. Doing this: (define (list-sum l k) (if (null?
L) (k 0) (list-sum (cdr l) k))) is clearly wrong -- it means that k will eventually receive the the sum of (cdr l) instead of all of l. Instead, use a new function there, which will sum up the first element of l too along with the value that it receives: (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l) (lambda (sum) (+ (car l) sum))))) This is getting closer, but still wrong.
But it's a good point to think about how things are working -- we're calling list-sum with a continuation that will itself receive the overall sum, and add the first item we see now to it. The missing part is evident in the fact that we're ignoring k. What we need is to compose k with this function -- so we do the same sum operation, then send the result to k: (define (list-sum l k) (if (null?
L) (k 0) (list-sum (cdr l) (compose k (lambda (s) (+ s (car l))))))) which is finally working.(BTW, remember that each of these lambda functions has its own "copy" of l.) You can try this with: (list-sum '(1 2 3 4) (lambda (x) x)) And finally note that this is the same as: (define (list-sum l k) (if (null? L) (k 0) (list-sum (cdr l) (lambda (s) (k (+ s (car l))))))) if you make the composition explicit.(You can also use this code in the intermediate+lambda student language, and click the stepper button to see how the evaluation proceeds -- this will take a while to go over, but you'll see how the continuation functions get nested, each with it's own view of the list. ).
Thank you so much, this is the answer I was looking for - the tip for the stepper is particularly helpful. Thank you! – Ixmatus Jan 7 '10 at 6:21 I just ran your exercise with the intermediate student with lambda language and stepper; I can't begin to tell you how immensely helpful that was.
Being able to see the path of execution that way cleared up all of my confusion! Thank you very much. – Ixmatus Jan 7 '10 at 18:28 Yeah -- it's a tool that is often misunderestimated as a "student tool"... – Eli Barzilay Jan 7 '10 at 18:33 very helpful, Eli, thank you.
I didn't know about the student languages and steppers, very nice. – Paul Sanwald Jan 7 '10 at 2:40.
Here's one way to help you "get a more concrete idea". Imagine if the collector were defined thus: (define (collector l p s) (display l) (newline) (display p) (newline) (display s) (newline)) You can see in the base case, if you pass in an empty list, it will call your function with arguments '(), 1, and 0. Now, work with a one-element list, and see what it'll call your function with.
Keep working up with longer and longer lists, until you figure out what's going on. Good luck!
Thank you, I'll try this. – Ixmatus Jan 7 '10 at 3:37 So, I understand exactly what happens when I pass in an empty list and I can see what is happening when I pass in smaller and successively larger lists; but I'm not grasping the "how" of those lambda expressions that have the collector for their body... – Ixmatus Jan 7 '10 at 3:43 Have you ever worked with an object-oriented language? If so, have you heard of the Decorator Pattern?
Each of the lambdas are basically decorating your collector with one more layer. – Chris Jester-Young Jan 7 '10 at 3:48 I have, but only in PHP and some Python. I've heard of Decorators in Python but never actually studied them.So is this function technically called a continuation too?
– Ixmatus Jan 7 '10 at 3:50.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.