Why is it returning this? - scheme

I am trying to use lambda, but when I test it in the console, it returns #<procedure:...esktop/Lab 4.rkt:105:2>.
My code is
(define (comp f g)
(lambda (x) (f (g x))))
And my test code is
(comp (lambda (x) (+ x 1)) 3)
For some reason, lambda is deferring the evaluation. Can someone please help?

comp takes two function arguments and returns a new function - their
composition:
(define (comp f g)
(lambda (x) (f (g x))))
;Value: comp
To test it, one has to call it on a number:
((comp (lambda (x) (+ x 1))
(lambda (x) (+ x 2)))
3)
;Value: 6

Related

Re-writing church numerals function

In SICP it defines the church numerals for positive numbers as follows:
(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f (n f) x))))
The following is my 'best attempt' to rewrite this for my own understanding, here passing explicit arguments to one function:
(define (church f x n)
(cond
((= n 0) x) ; zero case: return x
(else (f (church f x (- n 1)))))) ; otherwise f(f(f...(x))) n times
(church square 3 2)
81
And then redefining zero I would have:
(define (zero2 f)
(lambda (x) (church f x 0)))
And add-one as:
(define (add-1 n f)
(lambda (x) (church f x (+ n 1))))
Or, if we have to defer the f argument then adding a wrapper-lambda:
(define (add-1 n)
(lambda (f) (lambda (x) (church f x (+ n 1)))))
Do I have a correct understanding of this? if so, why the oh-so-complicated-syntax at the top for the add-1 or zero procedures (note: I'm guessing it's not that complicated and I'm just not fully understanding what it's doing). Any help would be greatly appreciated!
lambda calculus is a sub set of Scheme that does not allow more than one argument and lambda. With combinations of lambdas you can make any construct:
(define false (lambda (true) (lambda (false) false)))
(define true (lambda (true) (lambda (false) true)))
(define if (lambda (pred) (lambda (consequence) (lambda (alternative) ((pred consequence) alternative)))))
You might be wondering why I allow define since it isn't lambda. Well you don;t need it. It is just for convenience since with it you can try it out:
(((if true)
'result-true)
'result-false)
; ==> result-true
Instead of using the totally equal version:
((lambda (pred)
(lambda (consequence)
(lambda (alternative)
((pred consequence) alternative))))
(lambda (true) (lambda (false) true))
'result-true
'result-false)
Your function church is not lambda calculus since it does not return a church number and it takes more than one argument which is a violation. I have seen scheme functions to produce chuck numbers but any chuck number you should be able to do this to get the integer value:
((church-number add1) 0)
eg. zero:
(((lambda (f) (lambda (x) x)) add1) 0) ; ==> 0
Your version presupposes the existence of primitives like cond, 0, 1, =, and -. The point of all this is to show that you can implement such primitives starting from nothing but lambda.
SICP defines the Church numerals for positive numbers as follows:
(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f (n f) x))))
No, it doesn't. The correct definitions are
(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f ((n f) x)))))
f is a "successor step", and x is "zero value".
(f ((n f) x)) means, do with f and x whatever n would be doing with f and x, and then do f one more time to the result.
In other words, transform the "zero value" with the "successor step" function one more times than n would be transforming it.
Now,
> ((zero add1) 0)
0
> (((add-1 zero) add1) 0)
1
> (((add-1 (add-1 zero)) add1) 0)
2
etc. Or,
> (define plus1 (lambda (x) (cons '() x)))
> ((zero plus1) '(NIL))
'(NIL)
> (((add-1 zero) plus1) '(NIL))
'(() NIL)
> (((add-1 (add-1 zero)) plus1) '(NIL))
'(() () NIL)
Hopefully you can see how the Church numbers could be defined as binary functions as well:
(define zero (lambda (f x) x))
(define (add-1 n)
(lambda (f x) (f (n f x))))
(define plus1 (lambda (x) (cons '() x)))
(zero add1 0) ;=> 0
((add-1 zero) add1 0) ;=> 1
((add-1 (add-1 zero)) add1 0) ;=> 2
(zero plus1 '(NIL)) ;=> '(NIL)
((add-1 zero) plus1 '(NIL)) ;=> '(() NIL)
((add-1 (add-1 zero)) plus1 '(NIL)) ;=> '(() () NIL)
producing the same results as before.

scheme: order of internal definition

It's a problem in SICP book ch4,here is the code
(let ((a 1))
(define (f x)
(define b (+ a x))
(define a 5)
(+ a b))
(f 10))
the error message is “a: undefined; cannot use before initialization”,if I use lambda expression
((lambda (a)
(define (f x)
(define a 5)
(define b (+ a x))
(+ a b))
(f 10)) 1)
still dont work,but if I write this as procedure define,like this
(define (f a)
(define (g x)
(define b (+ a x))
(+ a b))
(g 10))
(f 1)
it runs without error,but these two are basically the same right? why the let and lambda expression failed? thanks.
Because it refers to the inner a, not the one in the let:
(let ((a 1))
(define (f x)
(define b (+ a x)) ; `a` here refers to
(define a 5) ; **this one**
(+ a b))
(f 10))
Internal defines are all placed in one shared scope. It is done so we can define mutually recursive functions.
If you switch the order of the two defines it'll work (put a definition above the b definition) because then a will be initialized before being used in the b initialization, but only if you use #lang racket.
In #lang sicp the following works:
(let ((a 1))
(define (f x)
(define a 5)
(define b (lambda () (+ a x)))
(+ a (b)))
(f 10))

Derivation of the Y-Combinator

While going through this article about Y-combinator (which I highly recommend), I stumbled over this transformation :
(define Y
(lambda (f)
((lambda (x) (x x))
(lambda (x) (f (x x))))))
Note that we can apply the inner lambda expression to its argument to get an equivalent version of Y:
(define Y
(lambda (f)
((lambda (x) (f (x x)))
(lambda (x) (f (x x))))))
Could someone please explain me how did we get to the second version of Y? Which steps did we follow to get there?
You are applying (lambda (x) (x x))(lambda (x) (f (x x)))
Do the application to get (lambda (x) (f (x x))(lambda (x) (f (x x))
Notice the left lambda creates 2 copies of its argument, which is the right lambda.

temporarily overwrite a globally defined function in Scheme let block?

suppose I have the following functions:
(define (g x) (f x))
(define (f x) (+ 1 x))
I would like to temporarily call g with a different f. For example, something like this:
(let ((f (lambda (x) (+ 2 x))))
(g 5))
I would like the code above to evaluate to 7, but it doesn't. Instead, it evaluates to 6, since g calls the f outside the scope of the let.
Is there a way to do this without redefining g inside the let, and without inlining the entire body of the definition of g in the let? (In practice, g may be a very large, complicated function).
What you are asking for is dynamic rather than lexical binding of 'f'. R6RS and R7RS support this with parameters. This will do what you want:
(define f (make-parameter (lambda (x) (+ 1 x))))
(define (g x) ((f) x))
(display (g 5))(newline)
(parameterize ((f (lambda (x) (+ 2 x))))
(display (g 5))(newline))
I'm not sure that you can, but I'm by no means a Scheme expert.
I realise that you're trying to achieve this without redefining g inside the let, but how about:
(define (h f x) (f x))
(define (g x) (h f x))
(define (f x) (+ 1 x))
(let ((f (lambda (x) (+ 2 x))))
(h f 5))
That way, you preserve the behaviour of g where it's currently being called. But where you want to temporarily have a different behaviour, you can call h instead.
A bit more code for clarification:
(let ((f (lambda (x) (+ 2 x))))
(display (g 5)) ; 6
(newline)
(h f 5)) ; 7
You could use an optional parameter in g to pass the f from the let expression.
(define (g x . args)
(if (null? args)
(f x)
((car args) x)))
and
(let ((f (lambda (x) (+ 2 x))))
(g 5 f))
I found a way to do exactly what I wanted, although I have a feeling many people will not consider this kosher:
(define (g x) (f x))
(define (f x) (+ 1 x))
(let ((old-f f))
(set! f (lambda (x) (+ 2 x)))
(let ((ans (g 5)))
(set! f old-f)
ans))
; -> 7
(g 5) ; -> 6
edit In response to the comment below, I wasn't even aware that fluid-let was a thing. It even already works on MIT-Scheme. That's actually exactly what I needed. If commenter below posts something like this as an answer, it will be made the accepted answer:
(define (g x) (f x))
(define (f x) (+ 1 x))
(fluid-let ((f (lambda (x) (+ x 2))))
(g 5)) ; -> 7
(g 5) ; -> 6

How to repeat a function call n times

I'm trying to create a function that wraps itself n times using a function called repeat
(define (repeat f n)
(if (= n 1)
f
(repeat (lambda (x) (f x)) (- n 1))))
((repeat inc 5) 2)
I'm expecting the result to be equal to
(inc (inc (inc (inc (inc 2))))) ; 7
But my result is 3
What am I doing wrong?
To be clear, I want repeat to return a function that accepts a single argument. f should not be applied until the return value of repeat is called with an argument.
e.g.,
(define inc5 (repeat inc 5))
(inc5 2) ; => 7
p.s.,
This is related but not identical to exercise 1.43 in SICP. I've solved the problem as it is presented there, but I'm curious if it can be solved this way too.
The problem with your definition is that (lambda (x) (f x)) is the same as f, i.e., your repeat repeats only once.
I think what you need is
(define (repeat f n)
(if (= n 1)
f
(lambda (x) (f ((repeat f (- n 1)) x)))))
PS. Note that you are using Scheme syntax under the Common Lisp tag; you might want to update one or the other.
Lets take a look at a similar function.
(define (repeat-exp fn ct)
(if (= ct 1)
fn
(repeat `(lambda (x) (,fn x)) (- ct 1))))
Calling it will get you
> (repeat-exp inc 5)
'(lambda (x)
((lambda (x)
((lambda (x)
((lambda (x)
((lambda (x)
(#<procedure:inc> x))
x))
x))
x))
x))
>
As you can see, your initial function only gets called once; in the innermost evaluation. If you want it to get called at each level, you need to call it there too.
(define (repeat-exp2 fn ct)
(if (= ct 1)
fn
`(lambda (x)
(,fn (,(repeat-exp2 fn (- ct 1)) x)))))
> (repeat-exp2 inc 5)
'(lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
(#<procedure:inc> x)))
x)))
x)))
x)))
>
Now you can write the numeric equivalent.
(define (repeat2 fn ct)
(if (= ct 1)
fn
(lambda (x)
(fn ((repeat2 fn (- ct 1)) x)))))
which should do what you wanted initially.
> (repeat2 inc 5)
#<procedure>
> ((repeat2 inc 5) 2)
7

Resources