(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))
Is there any way that I can improve add?
I'm getting the hang of Church encoding. [smile]
(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: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.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.
(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))