2

I am trying to implement a while loop using recursion with lambda, but I just don't understand how to do it.

I am supposed to start with this lambda expression:

((lambda (x) (x x)) (lambda (x) (x x))

My first question is why does this cause 'eternal' recursion? I try to understand how it works, but I just can't grasp it.

I also have this code to go after:

((lambda (x) (x x))
 (lambda (x) 
   (if (not (= i 0))
       (begin
         (display i)
         (set! i (- i 1))
         (x x))
       )))

This code causes a loop that prints from i = n to i = 0, but I don't understand this either. If someone would care to explain the use of lambda here I would be grateful :)

Edit: I have to use this lambda expression as my 'starting point', and I don't want to use macros (it's a voluntary excercise which I try to understand, so I want to follow the guidelines :))

user16655
  • 1,901
  • 6
  • 36
  • 60
  • While typically is implemented as a macro in Scheme. See this more or less duplicate question: http://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket – ben rudgers May 17 '15 at 03:56

1 Answers1

2

To see what happens when ((lambda (x) (x x)) (lambda (x) (x x)) is evaluated use the stepper in DrRacket. It can show you the steps an evaluation takes.

Write your expression in the definition window of DrRacket. Then choose the teaching language "Intermediate Student with lambda". Then click the stepper button (the green triangle followed by a bar).

You will see something that looks like the image (which uses a different program):

enter image description here

Update:

Try this program:

(define i 5)

((lambda (x) (x x))
 (lambda (x) 
   (if (not (= i 0))
       (x x)
       'ignore)))

Update:

(define i 5)

(define f
  (lambda (x) 
    (if (not (= i 0))
        (begin
          (display i)
          (set! i (- i 1))
          (x x))
        'done)))

(f f)

Or without any defines at all:

((lambda (f) (f f))
 (lambda (x) 
   (if (not (= i 0))
       (begin
         (display i)
         (set! i (- i 1))
         (x x))
       'done)))

And here without an external variable:

((lambda (f i) (f f i))
 (lambda (x i) 
   (if (not (= i 0))
       (begin
         (display i)
         (x x (- i 1)))
       'done))
 5)

Using a while function:

(define (while body . args)
  (apply body body args))

(while (lambda (loop i)
         (if (not (= i 0))
             (begin
               (display i)
               (loop loop (- i 1)))
             'done))
  5)
soegaard
  • 30,661
  • 4
  • 57
  • 106
  • I think it is `set!` the stepper can't handle. Maybe we can find a similar program to try? – soegaard May 16 '15 at 20:56
  • Thank you, that worked :) Maybe I'm a bit wiser, I'm not really sure. Is it possible to put the lambda expression into a function so it can be called from outside? – user16655 May 16 '15 at 21:12
  • (define f (lambda (x) (x x))) – soegaard May 16 '15 at 21:12
  • Perhaps you will like this blog post. It is about implementing recursion via the mechanism you are experimenting with. http://www.wisdomandwonder.com/article/6344/understanding-the-y-combinator-with-racket – soegaard May 16 '15 at 21:14
  • I read the article, but I'm still quite stuck at trying to generate a loop. The problem is that I want to send the condition and the body as parameters to the function, but I can't seem to understand how to combine this with the lambda expression... I have to use the lambda expression above also, so I'm just stuck. It's not a problem if I don't get it as it's a voluntary excercise, but it's frustrating that I just don't understand how it works. – user16655 May 17 '15 at 19:47
  • I have added one solution. – soegaard May 17 '15 at 19:51
  • Wait a minute - you already have the solution in your question. Am I misunderstanding you? – soegaard May 17 '15 at 19:54
  • So f is a function that takes one argument x. The intention is that `f` is be called with `(f f)` which means that `x` is bound to the same function. To loop the body simply needs to call itself and since `x` is bound to `f` we have that `(x x)` will call it self. – soegaard May 17 '15 at 19:56
  • Well, sort of. The solution is to use the eternal recursion with lambda expressions, and the example that's in my question is an example of how it works. What i need to do is get this inside a function, and be able to send the condition and the body as parameters to that function. So I want to say f.ex. (while (= i 0) (display i) (newline) (set! i (- i 1)), and the while function will take care of this. – user16655 May 17 '15 at 20:00
  • Okay - I have added a solution without an external variable. – soegaard May 17 '15 at 20:03
  • Thank you. I tried to wrapped this into a while function, but I just can't get it done. Thank you for your time, I think I have to realize that this is just to complicated for me... – user16655 May 17 '15 at 20:09
  • I have added a version with a while function. – soegaard May 17 '15 at 20:10
  • Thank you. I will look at this some more, it's almost there, but I don't want to have to write the lambda expression when I call the while function, I want it to be in the while function. I think I maybe will have to read a (lot) more about lambda before my exam ;-) – user16655 May 17 '15 at 20:37
  • In that case you will need to look into macros. – soegaard May 17 '15 at 20:42