removing nested lambdas from function definition - scheme

I have to remove every lambda from the following code, and I can't use other functions in the global space. (((f 1) 2) 3) should produce 6.
(define f (lambda (x)
(lambda (y)
(lambda (z)
(+ x y z)))))
I have tried using define in define, but the problem is with the (((f 1) 2) 3) having to give 6. I dont see how I can use the 2 and 3 inside function f, if they are given outside the function? It is OK if the lambdas are “under the hood,” they just have to not be visible.

Try
(define (f x)
(define (g y)
(define (h z)
(+ x y z))
h)
g)
or
(define (((f x) y) z)
(+ x y z))

Related

dont understood lambda expression on scheme

i try to realize what this expiration, and don't get it.
( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))
i think,
a is a number, and b is #t or #f,
on the if statement we ask if b is true, if yes return first expression(sum 3 numbers), else the second(Subtract 3 numbers)
what i need to write on Racket to run this?
i try
(define question( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))))
and than
(question 5 #f)
and nothing not going well in this language.
This is not a complete answer as I don't want to do your homework for you.
First of all formatting and indenting your code is going to help you in any programming language. You almost certainly have access to an editor which will do this. Below I've done this.
So, OK, what does a form like (λ (...) ...) denote? Well, its a function which takes some arguments (the first ellipsis) and returns the value of the last form in its body (the second ellipsis), or the only form in its body in a purely functional language.
So, what does:
(λ (a b)
(λ (x y)
...))
Denote? It's a function of two arguments, and it returns something: what is the thing it returns? Well, it's a form which looks like (λ (...) ...): you know what those forms mean already.
And finally we can fill out the last ellipsis (after correcting an error: (-x ...) is not the same as (- x ...)):
(λ (a b)
(λ (x y)
(if b
(+ x y a)
(- x y a))))
So now, how would you call this, and how would you make it do something interesting (like actually adding or subtracting some things)?
(lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a))))
is a function that takes two arguments (that's what (lambda (a b) ...) says).
You can use the substitution method to discover what it produces.
Apply it to 5 and #f:
((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f)
[Replace a with 5 and b with #f in the body]:
(lambda (x y) (if #f (+ x y 5) (- x y 5)))
And this is a function that takes two numbers and produces a new number.
(Note that the #f and the 5 became fixed by the application of the outer lambda.)
It's easier to use the function if we name it (interactions from DrRacket):
> (define question (lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))))
> (question 5 #f)
#<procedure>
which is as expected, based on the reasoning above.
Let's name this function as well:
> (define answer (question 5 #f))
and use it:
> (answer 3 4)
-6
or we could use it unnamed:
> ((question 5 #f) 3 4)
-6
or you could do it all inline, but that's a horrible unreadable mess:
> (((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f) 3 4)
-6

In MIT Scheme/Racket, can a value be both the operator and operand? i.e. (lambda (y) (y y))

For the function foo6, give a Curried application of the procedure which evaluates to 3.
(define foo6
(lambda (x)
(x (lambda (y) (y y)))))
I've defined a foo7 to see how the last line works
(define foo7 (lambda (y) (y y)))
Is there some "y" that can both be the operator and the operand?
Edit: The question should read:
Is there some "y" that can both be the operator and the operand that will not cause an error or infinite loop?
Question taken from the Structure and Interpretation of Computer Program (SICP) Sample Programming assignments:
https://mitpress.mit.edu/sicp/psets/index.html
From the "Introductory assignment," Exercise 11:
PDF Version: https://github.com/yangchenyun/learning-sicp/raw/master/practices/assignments/01.introductory-assignment/ps1_1.pdf
PS (Original Version):
https://mitpress.mit.edu/sicp/psets/ps1/ps1_1.ps
Yes. Scheme and Racket are both Lisp1s which means they only have one namespace and thus. the variable v can be any value including procedures.
The second you see something like (lambda (y) (y y)) it obvious what type y is a procedure by the way it is being applied. For any other values than a procedure it would end with a application error:
((lambda (y) (y y)) 5)
; ERROR: application: 5 is not a procedure
The procedure itself will probably expect itself as an argument so we can assume some sort of omega or z combinator.
We have higher order procedures you pass functions as values in operand position and to use them just put then in operator position:
(define (times n p)
(lambda (arg)
(let loop ((n n) (acc arg))
(if (<= n 0)
acc
(loop (sub1 n) (p acc))))))
(define double (lambda (v) (+ v v)))
(define test (times 3 double))
(test 5) ; ==> 40
Scheme is not alone on having this feature. The same code as above can be expressed just as easily in JavaScript as it also only have one namespace and parseInt(x) evaluates the variable parseInt to a value that gets applied with the argument you get from evaluating the variable x. They are just two variables, nothing special.
EDIT
Here is an example where (lambda (y) (y y)) is used in something usefull.
;; the Z combinator
(define Z
(lambda (f)
((lambda (y)
(y y))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(define (fib n)
((Z (lambda (helper)
(lambda (n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))))
n 0 1))
(fib 10) ; ==> 55
The Z combinator is the Y combinator for eager languages. It makes it possibly for self reference without mutating the environment.
Yes,
(define (foobar n)
((foo6
(lambda (u) (u (lambda (y)
(lambda (n)
(if (zero? n)
1
(* n ((y y) (- n 1)))))))))
n))
Y? I mean, why? Because
(foo6 x)
=
(x (lambda (y) (y y))
=
(x u) where u = (lambda (y) (y y))
i.e. (u y) = (y y)
So the argument to foo6 should be a function x expecting u such that u y = y y. So we give it the function such that
(foobar n)
=
((foo6 x) n)
=
((x u) n)
=
((u y) n) so, x = (lambda (u) (u (lambda (y) (lambda (n) ...))))
=
((y y) n) so, y = (lambda (y) (lambda (n) ...))
=
((lambda (n)
(if (zero? n)
1
(* n ((y y) (- n 1)))))
n)
and later, when / if ((y y) (- n 1)) needs to be evaluated, the same (lambda (n) ...) function is arrived at again as the result of (y y) application, and is used again when / if ((y y) (- (- n 1) 1)) needs to be evaluated.
Try it! What's (foobar 5) evaluating to? (ʎʇuǝʍʇpuɐpǝɹpunɥǝuo)
So, everything fits. Do u see y?
(lambda (y) (y y)) actually has a name: it is "U combinator".

Scheme Why does it seem that my else statement is not working?

. I am trying to teach my self some computer science skills independently. The problem I am working on wants me to create a way to choose the two biggest numbers out of three then find the sum of squares for the two numbers.
(define (pro x y z)
(cond( (and (< x y) (< x z)) (define a y)(define b z))
( (and(< y x) (< y z)) (define a x) (define b z))
( else ((define a x )(define b y))))
(+ (* a a) (* b b))
When I run the function with z being the smallest or tied for the smallest number I get the following error:
Error: #<undef> is not a function [pro, (anon)]
Why am I getting this error and how do I fix it?
I have been using repl.it to run this program, if that matters.
First, using define's that way is totally bizarre for Scheme code.
After that, I see two problems with the code. The first, the one that's creating the error you're getting, is that you have an extra layer of parens in the else clause. The following
((define a x) (define b y))
is going to evaluate the first define and try to apply it as a procedure. The evaluation of (define ...) returns the #undef which is the source of your error messsage.
If you fixed that problem, your next problem is that your sum of squares code is outside the scope of the defines in your cond and you'll find that a and b are not defined out there.
You should do something like this:
(define (max-of-3 x y z)
(cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y))))
(define (pro x y z)
(let-values (((a b) (max-of-3 x y z)))
(+ (* a a) (* b b))))
or even
(define (pro x y z)
(let-values
(((a b) (cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y)))))
(+ (* a a) (* b b))))

Scheme, higher order functions, and curried functions

I need to write a Scheme higher-order function that takes a function of two parameters as its parameter and returns a curried version of the function. I understand this much so far in terms of curried functions:
(define curriedFunction (lambda (x)
(if (positive? x)
(lambda (y z) (+ x y z))
(lambda (y z) (- x y z)))))
(display ((curriedFunction -5) 4 7))
(display "\n")
(display ((curriedFunction 5) 4 7))
If x is negative, it subtracts x y and z. If x is positive, it adds x, y, and z.
In terms of higher order functions I understand this:
(display (map (lambda (x y) (* x y)) '(1 2 3) '(3 4 5)))
And thirdly I understand this much in terms of passing functions in as arguments:
(define (function0 func x y)
(func x y))
(define myFunction (lambda (x y)
(* x y)))
(display (function0 myFunction 10 4))
In the code directly above, I understand that the function "myFunction" could have also been written as this:
(define (myFunction x y)
(* x y))
So now you know where I am at in terms of Scheme programming and syntax.
Now back to answering the question of writing a Scheme higher-order function that takes a function of two parameters as its parameter and returns a curried version of the function. How do I connect these concepts together? Thank you in advance, I truly appreciate it.
Here is a possible solution:
(define (curry f)
(lambda (x)
(lambda (y)
(f x y))))
The function curry takes the function f and returns a function with a single argument x. That function, given a value for its argument, returns another function that takes an argument y and returns the result of applying the original function f to x and y. So, for instance, (curry +) returns a curried version of +:
(((curry +) 3) 4) ; produces 7

Convert to CPS (Continuation Passing Style)

How do I convert these procedures in Scheme to CPS form?
(lambda (x y)
((x x) y))
(lambda (x)
(lambda (f)
(f (lambda (y)
(((x x) f) y))))
((lambda (x) (x x)
(lambda (x) (x x))
*This is not any homework!
See Programming Languages, Application and Interpretation, starting around Chapter 15. Chapter 18 talks about how to do it automatically, but if you're not familiar with thinking about expressing a function that does "what to do next", you'll probably want to try the finger exercises first.
Don't have someone do it for you: you'll really want to understand the process and be able to do it by hand, independent of Scheme or otherwise. It comes up especially in Asynchronous JavaScript web programming, where you really have no choice but to do the transform.
In the CPS transform, all non-primitive functions need to now consume a function that represents "what-to-do-next". That includes all lambdas. Symmetrically, any application of a non-primitive function needs to provide a "what-to-do-next" function, and stuff the rest of the computation in that function.
So if we had a program to compute a triangle's hypothenuse:
(define (hypo a b)
(define (square x) (* x x))
(define (add x y) (+ x y))
(sqrt (add (square a)
(square b))))
and if we state that the only primitive applications here are *, +, and sqrt, then all the other function definitions and function calls need to be translated, like this:
(define (hypo/k a b k)
(define (square/k x k)
(k (* x x)))
(define (add/k x y k)
(k (+ x y)))
(square/k a
(lambda (a^2)
(square/k b
(lambda (b^2)
(add/k a^2 b^2
(lambda (a^2+b^2)
(k (sqrt a^2+b^2)))))))))
;; a small test of the function.
(hypo/k 2 3 (lambda (result) (display result) (newline)))
The last expression shows that you end up having to compute "inside-out", and that the transformation is pervasive: all lambdas in the original source program end up needing to take an additional argument, and all non-primitive applications need to stuff "what-to-do-next" as that argument.
Take a close look at section 17.2 of the cited book: it covers this, as well as 17.5, which talks about why you need to touch ALL the lambdas in the source program, so that the higher-order case works too.
As another example of the transform, applied for a higher-order case, let's say that we have:
(define (twice f)
(lambda (x)
(f (f x))))
Then the translation of something like this is:
(define (twice/k f k1)
(k1 (lambda ...)))
... because that lambda's just a value that can be passed to k1. But of course, the translation needs to run through the lambda as well.
We must first do the inner call to f with x (and remember that all non-primitive function applications need to pass an appropriate "what-to-do-next!"):
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
...)))))
... take that value and apply it again to f...
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
(f fx-val ...))))))
... and finally return that value to k2:
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
(f fx-val k2))))))
;; test. Essentially, ((twice square) 7)
(define (square/k x k) (k (* x x)))
(twice/k square/k
(lambda (squaresquare)
(squaresquare 7
(lambda (seven^4)
(display seven^4)
(newline)))))
You need to choose to what level you need/want to CPS-transform.
If you just want (lambda (x y) ((x x) y)) in continuation-passing(CP) style, then (lambda (k x y) (k ((x x) y))) will do fine.
If you want its arguments to be treated as being in CP style too, then you need a little more.
Suppose first that only the second argument (y) is in CP form and is thus really something like (lambda (k) (k y0)) and so needs to be called with some continuation to extract its value, then you would need:
(lambda (k x y)
(y (lambda (y0) (k ((x x) y0)) )) )
Finally assume that both x and y are in CP style. Then you would need something like:
(lambda (k x y)
(x (lambda (x0)
(x (lambda (x1)
(y (lambda (y0)
(k ((x0 x1) y0)) ))))
Here you have the freedom to reorder the calls to x and y. Or maybe you only need one call to x, because you know its value does not depend on the continuation it is called with. For example:
(lambda (k x y)
(y (lambda (y0)
(x (lambda (x0)
(k ((x0 x0) y0)) ))))
The other expressions you asked about can be transformed similarly.

Resources