Original Post
Chapter 2 discussions go here. EDIT: Removed time period from title. [Edited by - Muhammad Haggag on April 8, 2007 1:45:33 AM]
Quote:
Original post by Ezbez
I'm working on Excercise 2.6 in Section 2.1.3. I can't understand the representation of add-1. I get caught up on the 'n' that is used as a function in the middle of it. I've never heard of a function 'n', and it doesn't seem to be defined if I try, say, (n 1). And yet when it evaluates (add-1 zero), everything is fine. No errors that 'n' isn't defined. What am I missing?
(define (doubler f) (lambda (x) (* 2 (f x))))(define (square x) (* x x))(define double-square (doubler square))(double-square 5)--> 50
Quote:They are a way of representing numbers in the lambda calculus. Other forms of data can be represented in a similar way. In Scheme, you also have more convenient primitives.
Original post by GameDev Doctor
On that same topic...I think it would be nice to have an explanation of church numerals and what the functions actually do. When I simply copy the procedures for add-1 and zero, it only resolves to <#procedure>, so how do you actually print it, extract the number, etc?
(define true (lambda (t) (lambda (f) t)))(define false (lambda (t) (lambda (f) f)))((true 1) 2)--> 1false works the same way, but returns its second argument.(define test (lambda (predicate) (lambda (then-clause) (lambda (else-clause) ((predicate then-clause) else-clause)))))(((test true) 1) 2)--> 1(((test false) 1) 2)--> 2Quote:
Original post by GameDev Doctor
On that same topic...I think it would be nice to have an explanation of church numerals and what the functions actually do. When I simply copy the procedures for add-1 and zero, it only resolves to <#procedure>, so how do you actually print it, extract the number, etc?
(define (num->church n) (if (= n 0) zero (add-1 (num->church (- n 1)))))(define (church->num n) ((n (lambda (x) (+ 1 x))) 0))> (church->num zero)0> (church->num (add-1 zero))1> (church->num (add-1 (add-1 zero)))2> (church->num (num->church 10))10true : (\xy.x)false : (\xy.y)if : (\xyz.xyz)if true a b=(\xyz.xyz) (\xy.x) a b=(\xy.x) a b=azero = \sz.zsucc = \n.\sz.s (n s z)iszero == (\n.n (\x.false) true)or(define zero? (lambda (n) ((n (lambda (x) false)) true)))5 = s(s(s(s(s(0)))))(5 1+ 0) = (1+ (1+ (1+ (1+ (1+ 0))))) = 5Quote:
Original post by Ezbez
Thanks you two. Doing Church Booleans let me understand this. Once I got and done, I found or and not pretty easy. Now onto Church Numerals!
This has left me with one question, though. Why do they curry the functions? Is it just style, or does it actually provide any benefit? I find that they lead to more errors, and ones that are harder to find since they won't instantly come up as a syntax error.
doubleAll :: [Int] -> [Int]doubleAll = map (2*)sum :: [Int] -> Intsum = foldl (+) 0elem :: Eq a => a -> [a] -> Boolelem x = any (== x)(define (add a b) ((a (lambda (n) (lambda (f) (lambda (x) (f ((n f) x)))))) b))(define (mul a b) ((a (lambda (x) (add x b))) zero))(define i 0.2)(define (f x) (if (not(> x (- 100 i))) (+ x i) (+ 100 (f (+ (- x 100) i i))) ))(define (g x y) (if (= x 0) y (g (- x i) (f y)) ))(define (h x) (g (- x 100) 100))(h 300)Quote:
Original post by @root
Hey again.
It's been a few weeks or so, since I programmed Scheme. To get myself starting again, I've created a a little app that solves a certain problem.
...
I'd like i to be as small as possible, while I give an argument running in the thousands to h. The problem is, that it is unusably slow at the moment. I've been braking my head over it, but I'm stuck. Could anyone give me some help?
(define (g x y) (display x) (newline) (if (= x 0) y (g (- x i) (f y))))(not(> x (- 100 i)))to(<= x (- 100 i)) (define i 0.2)(define (f x) (if (<= x (- 100 i)) (+ x i) (+ 100 (f (+ (- x 100) i i)))))(define (g x y) (if (<= x 0) y (g (- x i) (f y))))(define (h x) (g (- x 100) 100))(+ 100 (f (+ (- x 100) i i)))))(define i 0.2) (define (f2 x) (define (tail-f x accum) (if (<= x (- 100 i)) (+ x i accum) (tail-f (+ (- x 100) i i) (+ accum 100)))) (tail-f x 0))(define (g2 x y) (if (<= x 0) y (g2 (- x i) (f2 y))))(define (h2 x) (g2 (- x 100) 100))(define (test-f x) (print (time (f x))) (newline) (print (time (f2 x))))> (test-f 3000000)cpu time: 601 real time: 661 gc time: 03012048.2000019923cpu time: 80 real time: 80 gc time: 03012048.2000019923>> (test-f 90000000)cpu time: 29633 real time: 104190 gc time: 325490361445.80302358cpu time: 3946 real time: 32086 gc time: 77190361445.80302356(define i 0.2) (define (f3 x) (let ((count-calls (truncate (/ (- x i) (- 100 (* 2 i)))))) (+ i (* 100 count-calls) (- x (* count-calls 99.6)))))(define (g3 x y) (if (<= x 0) y (g3 (- x i) (f3 y))))(define (h3 x) (g3 (- x 100) 100))(define (test-h x) (print (time (h x))) (newline) (print (time (h2 x))) (newline) (print (time (h3 x))))> (test-h 300)cpu time: 50 real time: 50 gc time: 05724.99999999906cpu time: 50 real time: 50 gc time: 05724.999999999088cpu time: 0 real time: 0 gc time: 05725.000000000055>>> (test-h 600)cpu time: 57493 real time: 68779 gc time: 67902337805.3998170984cpu time: 21080 real time: 21140 gc time: 44562337805.3998170956cpu time: 10 real time: 10 gc time: 02337813.800000025;;Old, not working version;(define (same-parity a . z) (define (same-parity-it r thelist mod listz) (cond ((null? listz) thelist) ((= r (% (car listz) mod)) (same-parity-it r (cons thelist (car listz)) mod (cdr listz))) (else (same-parity-it r thelist mod (cdr listz))) ) ) (if (null? z) a (same-parity-it (% a 2) (list a) 2 z) ) );;working version, fixed by switching (cons (car listz) thelist) around and adding reverse at the end;(define (same-parity a . z) (define (same-parity-it r thelist mod listz) (cond ((null? listz) thelist) ((= r (% (car listz) mod)) (same-parity-it r (cons (car listz) thelist) mod (cdr listz))) (else (same-parity-it r thelist mod (cdr listz))) ) ) (if (null? z) a (reverse (same-parity-it (% a 2) (list a) 2 z)) ) )Quote:You're fixing the code. The data structure in your first example is very different from the data structure in your second example: it's not a simple question of layout, but of data structure design.
I eventually fixed both, but I'd like some help figuring out how to design these functions so that I dont have to spend twice as much time fixing the layout as writing the code.
(1 2 3 4)is shorthand for the structure(cons 1 (cons 2 (cons 3 (cons 4 (list)))))Which is a linked list, and is called list or proper list in lisp.Read the very top of the page again. (define (same-parity num-list) (let ((first (car num-list)) (therest (cdr num-list))) (cond ((null? therest) num-list) ((= (modulo first 2) (modulo (car therest) 2)) (cons first (same-parity therest))) (else (same-parity (cons first (cdr therest)))))))
Quote:
Original post by SamLowry
Both look ok to me (maybe you should curry your functions, but that's a detail), but you can simplify a bit.
Quote:
Another, even simpler way to write down mul would be to again see the church numeral as an adder: (b succ) is a function which adds b to its argument (currying in action): (b succ) 3 = b + 3. Hence, we can write
mul = \a b.\s z.a (b s) z
===
mul = \a b.\s.a (b s)
===
mul = \a b s.a (b s)
(define zero (lambda (f) (lambda (x) x)))(define one (lambda (f) (lambda (x) (f x))))(define two (lambda (f) (lambda (x) (f (f x)))))(define (add-1 n) (lambda (f) (lambda (x) (f ((n f) x)))))(define (add n1 n2) (lambda (f) (lambda (x) ((n2 f) ((n1 f) x)))))(define (power base p) (p base))(define (multiply n1 n2) ((n2 (lambda (y) (add n1 y))) zero)); I took these from SamLowry--Don't think I'm smart enough to come up with; these on my own :P(define (num->church n) (if (= n 0) zero (add-1 (num->church (- n 1)))))(define (church->num n) ((n (lambda (x) (+ 1 x))) 0))This topic has been locked by a moderator. New replies are not allowed.
GameDev.net uses cookies to ensure you have the best experience on our platform. Learn more