4

I'd like to ask if you can help me with a programming exercise. I'm trying to make a lambda expression of this form:

λz.x(yz)

The way I understand this, is that y is a function, applied to the value z. Then x is a function applied to what comes out if the function y is applied to z. The whole expression then says this:

λz.x(yz) means: Do the following with the argument z:
  1. Apply the function y to z.
  2. Apply the function x to what comes out of the first procedure.

I've made this program to try to get Scheme to do all of the above:

(define (zlamb)
  (lambda (z)
    (lambda (x)
      (* (lambda (y) (* z 4)) 2))))

When I run it, all I get is this:

Welcome to DrRacket, version 5.3 [3m].
Language: R5RS; memory limit: 128 MB.
( (zlamb) 3)
procedure:...lambdaefing1.rkt:3:4
>

Can anybody please explain to me what I'm doing wrong? What I wanted to get is (3 * 4) * 2 = 24. So I made (or thought I made) the inner function y = z * 4 and the outer function x = y(z) * 2.

I've searched all over the internet for explanations, but can't find the particular needle I'm looking for in the haystack.

2 Answers 2

2

Everything Arafinwe says makes perfect sense to me. However, I'm still worried that you may be misunderstanding your assignment.

To be more specific, the lambda calculus is essentially a subset of scheme terms, with a very slightly different syntax. In particular, the lambda calculus term λz. is written in Scheme as (lambda (z) ). Well, with the caveat that the must also be translated.

The application (zx) is written in Scheme simply as (z x). Also, mathematicians are lazy, and they sometimes leave out parens, so a(bc) is actually a shorthand for (a (b c)). I'm struggling not to directly translate your term, here :).

Note, though, that a direct translation of your given lambda calculus term into Scheme will not be a well-formed program, because it contains free references ("unbound variables") y and z.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm worried about exactly the same thing, as I'm impying in my first comment. I've been thinking if I was doing something wrong by using lambda for the x and y. I'm pretty sure yz means apply the function y to the term z and x(yz) means apply the function x to yz. So you're saying I have to use (define z (functionlity this or that)) to be able to make the call (z x)?
Yes, that's right; the lambda-calculus term you provide has free variable references, and can't be evaluated except in a context that binds those variables.
Thank you John, sorry I mixed up variables. ...(define y(??)) to be able to make the call (y z)... - is what I should have written. Think I'm a little closer to understanding this lambda calculus.
1

Let's break your program down from the inside out:

(* z 4)

Multiply z by 4

(lambda (y) (* z 4))

A function returning z*4

(* (lambda (y) (* z 4)) 2)

The product of that function and 2. You cannot multiply a function by 2. This is likely what is causing your bug; perhaps you mean to do the following:

(define (zlamb)
  (lambda (z)
    ((lambda (y) (* 2 (y z))) ; Note the two parenthesis before lambda - this is a function application
      (lambda (z2) (* z2 4)))))

Firstly note that both zs end up being the same, since z2 is bound to the value of the z in line 3. They could in fact both be named z but I named them differently to prevent confusion.

It further appears that your basic problem is in confusing the name of a function with its arguments:

(lambda (name) ...)

creates an anonymous function with an argument of name. The reason we are able to refer to the anonymous function in line 4 as y in line 3 is by making the construction

((lambda (y) ...) (lambda ...))

which passes the second function as an argument to the first, thus naming it y.

6 Comments

Thanks a lot Arafinwe, worked like a charm. By calling it with ((zlamb) 3) the result was 24 as expected. You've explained well how to nest lambda definitions. In my assignment I have to do an even deeper nesting, but I believe I got the idea. If it turns out I haven't, "I'll be back", to use a famous quote!
@TheódórNorðkvist No problem! By the way, if you wanted to make a function the normal way, the correct syntax is (define (zlamb z) ...) or (define zlamb (lambda (z) ...)). Then, you can call the function by doing (zlamb 3) instead of ((zlamb) 3). Finally, if you found the answer helpful, you can click the outline of a checkmark next to the answer and the "up" button. This lets people know that the question has been answered by this answer.
Will vote up when I get 15 in reputation, thanks again. I've already accepted the answer, but does it mean I have to ask another question when I try to do a deeper nesting tomorrow and get in trouble? You only know if you understand something, when you try to apply it and either fail or succeed!
@TheódórNorðkvist If you have another problem, you may certainly ask another question. However, consider if there may be a way to generalize your problems into one question.
I changed my code to use define instead of lambda, because lambda should only be used for the z-part. So the equivalence of λz.x(yz) is the following, called with an argument in the last line. Now the only problem left is nesting it deeper, first as λy.(λz.x(yz)) then as λx.(λy.(λz.x(yz))). (define (zlamb) (lambda (z) (define (x yz) (* yz 2) ) (define (y z) (+ z 3) ) (x (y z)) ) ) ((zlamb) 5) PS Does anybody know how to split into paragraphs?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.