0

So the p-cons procedure takes x and y as input and returns an anonymous procedure that takes z as input (and remembers x and y?) What I'm struggling to understand is when I run this in REPL:

(p-car (p-cons 1 2))

it returns 1, and 2 with p-cdr, which is what they are intended to do.However I just can't understand how they are able to access the values of the p-cons procedure? Can someone explain how this works and what I might not be grasping fully? Here are the procedures:

 (define (p-cons x y)
      (lambda (z) (z x y)))

    (define (p-car proc)
      (proc (lambda (x y) x)))

    (define (p-cdr proc)
      (proc (lambda (x y) y)))
kneeoh
  • 5
  • 2

2 Answers2

2

To see why 1 and 2 are not lost, you can step through the expression as follows:

(p-car (p-cons 1 2))
=> (p-car (lambda (z) (z 1 2)))
=> ((lambda (z) (z 1 2)) (lambda (x y) x))
=> ((lambda (x y) x) 1 2)
=> 1

(p-cons 1 2) is essentially producing the procedure: (lambda (z) (z 1 2)). You can pass any function f to this procedure and it will return (f 1 2). For example:

((lambda (z) (z 1 2)) +)                  ; => 3
((lambda (z) (z 1 2)) (lambda (x y) x))   ; => 1 
((lambda (z) (z 1 2)) (lambda (x y) y))   ; => 2
assefamaru
  • 2,751
  • 2
  • 10
  • 14
1

Scheme procedures are closures. They can references variables from the environment in which the procedure was defined.

When variables are referenced in a closure, they won’t be destroyed when you leave the scope where it was defined. Instead, they will live on until the closure still exists.

A textbook example of using closures is a counter:

<!-- language: scheme -->
(define (make-counter)
  (let ((x 0))
    (lambda ()
      (set! x (+ x 1))
      x)))

(define counter (make-counter))

(counter) => 1
(counter) => 2
(counter) => 3
(counter) => 4

Here, the (lambda () (set! x (+ x 1)) x) procedure references x from the environment where it was defined (i.e. x from make-counter). So, even though the execution of make-counter has been finished, x variable continues to live on, because it’s referenced in the procedure counter.

Please refer to the question What is a ‘Closure’ for more information (the answer that has examples in Scheme might be most relevant).

Community
  • 1
  • 1