Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lambda functions and memory in scheme

I don't understand why if I write

(define (iter-list lst)
  (let ((cur lst))
    (lambda ()
      (if (null? cur)
          '<<end>>
          (let ((v (car cur)))
            (set! cur (cdr cur))
            v)))))

(define il2 (iter-list '(1 2)))

and call (il2) 2 times I have printed: 1 then 2 (that's the result I want to have) But if I don't put (lambda () and apply (il2) 2times I obtain then 1 In other words why associating the if part to a function lambda() makes it keep the memory of what we did when we applied the function before?

like image 583
morg Avatar asked Dec 06 '25 19:12

morg


1 Answers

This is what's happening. First, it's important that you understand that when you write this:

(define (iter-list lst)
  (let ((cur lst))
    (lambda ()
      ...)))

It gets transformed to this equivalent form:

(define iter-list
  (lambda (lst)
    (let ((cur lst))
      (lambda ()
        ...))))

So you see, another lambda was there in the first place. Now, the outermost lambda will define a local variable, cur which will "remember" the value of the list and then will return the innermost lambda as a result, and the innermost lambda "captures", "encloses" the cur variable defined above inside a closure. In other words: iter-list is a function that returns a function as a result, but before doing so it will "remember" the cur value. That's why you call it like this:

(define il2 (iter-list '(1 2))) ; iter-list returns a function
(il2)                           ; here we're calling the returned function

Compare it with what happens here:

(define (iter-list lst)
  (let ((cur lst))
    ...))

The above is equivalent to this:

(define iter-list
  (lambda (lst)
    (let ((cur lst))
      ...)))

In the above, iter-list is just a function, that will return a value when called (not another function, like before!), this function doesn't "remember" anything and returns at once after being called. To summarize: the first example creates a closure and remembers values because it's returning a function, whereas the second example just returns a number, and gets called like this:

(define il2 (iter-list '(1 2))) ; iter-list returns a number
(il2)                           ; this won't work: il2 is just a number!
il2                             ; this works, and returns 1
like image 122
Óscar López Avatar answered Dec 08 '25 17:12

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!