Question

Question:

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

This was #1 on the midterm, I put "81 9" he thought I forgot to cross one out lawl, so I cross out 81, and he goes aww. Anyways, I dont understand why it's 81.

I understand why (lambda (x) (* x x)) (* 3 3) = 81, but the first lambda I dont understand what the x and y values are there, and what the [body] (x y) does.

So I was hoping someone could explain to me why the first part doesn't seem like it does anything.

Was it helpful?

Solution

This needs some indentation to clarify

((lambda (x y) (x y))
 (lambda (x) (* x x))
 (* 3 3))
  • (lambda (x y) (x y)); call x with y as only parameter.
  • (lambda (x) (* x x)); evaluate to the square of its parameter.
  • (* 3 3); evaluate to 9

So the whole thing means: "call the square function with the 9 as parameter".

EDIT: The same thing could be written as

((lambda (x) (* x x))
 (* 3 3))

I guess the intent of the exercise is to highlight how evaluating a scheme form involves an implicit function application.

OTHER TIPS

Let's look at this again...

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

To evaluate a form we evaluate each part of it in turn. We have three elements in our form. This one is on the first (function) position:

(lambda (x y) (x y))

This is a second element of a form and a first argument to the function:

(lambda (x) (* x x))

Last element of the form, so a second argument to the function.

(* 3 3)

Order of evaluation doesn't matter in this case, so let's just start from the left.

(lambda (x y) (x y))

Lambda creates a function, so this evaluates to a function that takes two arguments, x and y, and then applies x to y (in other words, calls x with a single argument y). Let's call this call-1.

(lambda (x) (* x x))

This evaluates to a function that takes a single argument and returns a square of this argument. So we can just call this square.

(* 3 3)

This obviously evaluates to 9.

OK, so after this first run of evaluation we have:

(call-1 square 9)

To evaluate this, we call call-1 with two arguments, square and 9. Applying call-1 gives us:

(square 9)

Since that's what call-1 does - it calls its first argument with its second argument. Now, square of 9 is 81, which is the value of the whole expression.

Perhaps translating that code to Common Lisp helps clarify its behaviour:

((lambda (x y) (funcall x y)) (lambda (x) (* x x)) (* 3 3))

Or even more explicitly:

(funcall (lambda (x y) (funcall x y))
         (lambda (x) (* x x))
         (* 3 3))

Indeed, that first lambda doesn't do anything useful, since it boils down to:

(funcall (lambda (x) (* x x)) (* 3 3))

which equals

(let ((x (* 3 3)))
  (* x x))

equals

(let ((x 9))
  (* x x))

equals

(* 9 9)

equals 81.

The answers posted so far are good, so rather than duplicating what they already said, perhaps here is another way you could look at the program:

(define (square x) (* x x))

(define (call-with arg fun) (fun arg))

(call-with (* 3 3) square)

Does it still look strange?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top