tags:

views:

303

answers:

4

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 its 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 doesnt seem like it does anything.

+9  A: 

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.

ddaa
+5  A: 

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.

Michał Kwiatkowski
+2  A: 

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.

Luís Oliveira
+1  A: 

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?

grettke