Re-writing church numerals function - scheme

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.

Related

scheme question code don't know why wrong

I want to solve the scheme problem
I define the code two, three, sq, plus
two is f(f(x)) // three is f(f(f(x)))
sq is square function ex ((two sq)3) is 81
plus is
(define (plus m n)
(lambda (f) (lambda (x) (m f (n f x))
I don't know why wrong that please let me know
You are confusing arity of functions. three and two are not functions of two parameters. They are functions that take a parameter and return a function. That returned function again takes a parameter.
Try the evaluating the following:
(let ((inc (lambda (x) (+ x 1))))
(list ((three inc) 0)
((two inc) 0)))
Your plus should be:
(define (plus m n)
(lambda (f) (lambda (x) ((m f) ((n f) x)))))
Now this should give you (3 2 5)
(let ((inc (lambda (x) (+ x 1))))
(list ((three inc) 0)
((two inc) 0)
(((plus two three) inc) 0)))

Create k size permutations without to define more functions

is it possible to implement Scheme function (one function - its important) that gets a list and k, and retreive the permutations in size of k, for example: (1 2 3), k=2 will output { (1,1) , (1,2) , (1,3) , (2,1) , (2,2) , ..... } (9 options).?
Its possible to do anything without defining anything as long as you have lambda:
(define (fib n)
;; bad internal definition
(define (helper n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))
(helper n 0 1))
Using Z combinator:
(define Z
(lambda (f)
((lambda (g)
(f (lambda args (apply (g g) args))))
(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))
Now we are never calling Z so we can substitute the value of Z for Z in the function and it will do the same:
(define (fib n)
(((lambda (f)
((lambda (g)
(f (lambda args (apply (g g) args))))
(lambda (g)
(f (lambda args (apply (g g) args))))))
(lambda (helper)
(lambda (n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))))
n 0 1))
There you go, Saved by Alonzo Church.
It is not only possible, it is easy. Just use a loop:
(define permute
(lambda (k lst)
(let loop ((result (map list lst))
(i 1))
(if (= i k)
result
(loop
;; code to add each element of the original list
;; to each element of the result list
(1+ i))))))

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

Scheme - nested definition confusion

I'm currently stuck on a problem creating func and am a beginner at Scheme. In order to achieve such a result, will I have to define double inside func?
(func double 3 '(3 5 1))
would return (24 40 8) because each element is doubled 3 times.
No, double needs to be outside func because it will be passed as a parameter (bound to f) to func:
(define (double n) (* 2 n))
(define (times f e t)
(if (= t 0)
e
(times f (f e) (- t 1))))
(define (func f t lst)
(map (lambda (e) (times f e t)) lst))
then
> (func double 3 '(3 5 1))
'(24 40 8)
OTOH, in this case times could be defined inside func, but it's a reusable procedure so I'd leave it outside.
If I understand your question correctly, here's one way you can implement func:
(define (func f n lst)
(do ((n n (sub1 n))
(lst lst (map f lst)))
((zero? n) lst)))
Example usage:
> (func (lambda (x) (* x 2)) 3 '(3 5 1))
=> (24 40 8)
#lang racket
(define (repeat f x n)
(cond [(= n 0) x]
[else (f (repeat f x (- n 1)))]))
(define (func f n xs)
(map (λ(x) (repeat f x n)) xs))
(define (double x)
(* 2 x))
(func double 3 '(3 5 1))
Possibly something like this:
(define (cmap fun arg1 lst)
(map (lambda (x) (fun arg1 x)) lst))
But really you want to do this (cmap list 1 (get-some-calc x) (get-list)) but it's very difficult to make it take any curried argument and perhaps you want more than one list. You do it like this:
(let ((cval (get-come-calc x)))
(map (lambda (x) (list 1 cval x)) (get-list)))

Length function in " The Seasoned Schemer"

I have been reading The Seasoned Schemer and i came across this definition of the length function
(define length
(let ((h (lambda (l) 0)))
(set! h (L (lambda (arg) (h arg))))
h))
Later they say :
What is the value of (L (lambda (arg) (h arg)))? It is the function
(lambda (l)
(cond ((null? l) 0)
(else (add1 ((lambda (arg) (h arg)) (cdr l))))))
I don't think I comprehend this fully. I guess we are supposed to define L ourselves as an excercise. I wrote a definition of L within the definition of length using letrec. Here is what I wrote:
(define length
(let ((h (lambda (l) 0)))
(letrec ((L
(lambda (f)
(letrec ((LR
(lambda (l)
(cond ((null? l) 0)
(else
(+ 1 (LR (cdr l))))))))
LR))))
(set! h (L (lambda (arg) (h arg))))
h)))
So, L takes a function as its argument and returns as value another function that takes a list as its argument and performs a recursion on a list. Am i correct or hopelessly wrong in my interpretation? Anyway the definition works
(length (list 1 2 3 4)) => 4
In "The Seasoned Schemer" length is initially defined like this:
(define length
(let ((h (lambda (l) 0)))
(set! h (lambda (l)
(if (null? l)
0
(add1 (h (cdr l))))))
h))
Later on in the book, the previous result is generalized and length is redefined in terms of Y! (the applicative-order, imperative Y combinator) like this:
(define Y!
(lambda (L)
(let ((h (lambda (l) 0)))
(set! h (L (lambda (arg) (h arg))))
h)))
(define L
(lambda (length)
(lambda (l)
(if (null? l)
0
(add1 (length (cdr l)))))))
(define length (Y! L))
The first definition of length shown in the question is just an intermediate step - with the L procedure exactly as defined above, you're not supposed to redefine it. The aim of this part of the chapter is to reach the second definition shown in my answer.

Resources