diff options
Diffstat (limited to 'other')
-rw-r--r-- | other/seasoned_schemer.scm | 638 |
1 files changed, 635 insertions, 3 deletions
diff --git a/other/seasoned_schemer.scm b/other/seasoned_schemer.scm index e81f07d..bcbad30 100644 --- a/other/seasoned_schemer.scm +++ b/other/seasoned_schemer.scm @@ -44,6 +44,14 @@ (eqlist? '(((this) is (a)) nontrivial (list)) '(((this) is (a)) nontrivial (list))) ; #t +; needed in not-mechanics +(define one? + (lambda (x) + (zero? (sub1 x)))) + +(one? 2) ; #f +(one? 1) ; #t + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Chapter 01: Welsome Back to the Show @@ -931,7 +939,8 @@ Ns ; (12 11 10 9 5 2 1 4) (S 1000) (counter)))) -(supercounter deep) ; 1233002, b/c I ran with something else first +; takes a long time to run +;(supercounter deep) ; 1233002, b/c I ran with something else first (define counter) (define set-counter) @@ -947,7 +956,8 @@ Ns ; (12 11 10 9 5 2 1 4) (set-counter 0) -(supercounter deep) ; 500500 +; takes a long time to run +;(supercounter deep) ; 500500 (set-counter 0) (define deepM (let ((Rs (quote ())) @@ -963,7 +973,8 @@ Ns ; (12 11 10 9 5 2 1 4) result) exists))))) -(supercounter deepM) ; 1000 +;this takes a long time to run +;(supercounter deepM) ; 1000 ; "A LISP programmer knows the value of everything but the cost of nothing" @@ -1054,3 +1065,624 @@ Ns ; (12 11 10 9 5 2 1 4) (lambda (c) (c (lambda (s a d) d)))) +(define kons + (lambda (a d) + (let ((c (bons a))) + (set-kdr c d) + c))) + +(define kounter) +(define set-kounter) +(define konsC + (let ((N 0)) + (set! kounter (lambda () N)) + (set! set-kounter (lambda (x) (set! N x))) + (lambda (a b) + (set! N (add1 N)) + (kons a b)))) + +(set-kounter 33) +(kounter) ; 33 +(set-kounter 0) + +(define add-at-end + (lambda (l) + (cond + ((null? (kdr l)) + (konsC (kar l) + (kons (quote egg) (quote ())))) + (else (konsC (kar l) + (add-at-end (kdr l))))))) + +(add-at-end (lots 3)) +(kounter) ; 3 + +(define add-at-end-too + (lambda (l) + (letrec + ((A (lambda (ls) + (cond + ((null? (kdr ls)) + (set-kdr ls (konsC (quote egg) (quote ())))))))) + (A l) + l))) + +(define set-kdr + (lambda (c x) + ((c (lambda (s a d) s)) x))) + +(define lots + (lambda (m) + (cond + ((zero? m) (quote ())) + (else (kons (quote egg) + (lots (sub1 m))))))) + +(define lenkth + (lambda (l) + (cond + ((null? l) 0) + (else (add1 (lenkth (kdr l))))))) + +(lots 8) ; [procedure] +(lenkth (lots 9)) ; 9 + +(set-kounter 0) +(define dozen (lots 12)) +(kounter) ; 0 + +(define bakers-dozen + (add-at-end dozen)) + +(kounter) ; 12 + +(lenkth bakers-dozen) ; 13 + +(define bakers-dozen-too (add-at-end-too dozen)) + +(kounter) + +(define eklist? + (lambda (ls1 ls2) + (cond + ((null? ls1) (null? ls2)) + ((null? ls2) #f) + (else (and (eq? (kar ls1) (kar ls2)) + (eklist? (kdr ls1) (kdr ls2))))))) + +(define same? + (lambda (c1 c2) + (let ((t1 (kdr c1)) + (t2 (kdr c2))) + (set-kdr c1 1) + (set-kdr c2 2) + (let ((v (= (kdr c1) (kdr c2)))) + (set-kdr c1 t1) + (set-kdr c2 t2) + v)))) + +(same? bakers-dozen bakers-dozen-too) ; #f .... hmmm + +(define last-kons + (lambda (ls) + (cond + ((null? (kdr ls)) ls) + (else (last-kons (kdr ls)))))) + +(define long (lots 12)) + +(set-kdr (last-kons long) long) + +;(lenkth long) ; haha! looped around! + +(define finite-lenkth + (lambda (p) + (call-with-current-continuation + (lambda (infinite) + (letrec + ((C (lambda (p q) + (cond + ((same? p q) (infinite #f)) + ((null? q) 0) + ((null? (kdr q)) 1) + (else (+ (C (sl p) (qk q)) 2))))) + (qk (lambda (x) (kdr (kdr x)))) + (sl (lambda (x) (kdr x)))) + (cond + ((null? p) 0) + (else (add1 (C p (kdr p)))))))))) + +(finite-lenkth long) ; #f yay! + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Chapter 19: Absconding with the Jewels + +; {{ The Twentieth Commandment }} +; When thinking about a value created with (letcc ...), write down the +; function that is equivalent but does not forget. Then, when you use it, +; remember to forget. + +(define deep&co + (lambda (m k) + (cond + ((zero? m) (k (quote pizza))) + (else + (deep&co (sub1 m) (lambda (x) + (k (cons x (quote ()))))))))) + +(deep&co 0 (lambda (x) x)) ; pizza +(deep&co 6 (lambda (x) x)) ; ((((((pizza)))))) + +(define two-layers + (lambda (p) + (cons + (cons p (quote ())) + (quote ())))) + +(define deep&coB + (lambda (m k) + (cond + ((zero? m) + (let () + (set! toppings k) + (k (quote pizza)))) + (else + (deep&coB (sub1 m) + (lambda (x) + (k (cons x (quote ()))))))))) + +(define two-in-a-row? + (letrec + ((W (lambda (a lat) + (cond + ((null? lat) #f) + (else + (let ((nxt (car lat))) + (or (eq? nxt a) + (W nxt (cdr lat))))))))) + (lambda (lat) + (cond ((null? lat) #f) + (else (W (car lat) (cdr lat))))))) + +; it's not two-in-a-row*? +(two-in-a-row? '(((tomato) paste (tastes)) so (so great))) ; #f +(two-in-a-row? '(a a)) ; #t + +(define leave) + +(define walk + (lambda (l) + (cond + ((null? l) (quote ())) + ((atom? (car l)) (leave (car l))) + (else + (let () + (walk (car l)) + (walk (cdr l))))))) + +(define start-it + (lambda (l) + (call-with-current-continuation + (lambda (here) + (set! leave here) + (walk l))))) + +(define fill) + +(define waddle + (lambda (l) + (cond + ((null? l) (quote ())) + ((atom? (car l)) + (let () + (call-with-current-continuation + (lambda (rest) + (set! fill rest) + (leave (car l)))) + (waddle (cdr l))) + (else (let () + (waddle (car l)) + (waddle (cdr l)))))))) + +(define start-it2 + (lambda (l) + (call-with-current-continuation + (lambda (here) + (set! leave here) + (waddle l))))) + +(define get-next + (lambda (x) + (call-with-current-continuation + (lambda (here-again) + (set! leave here-again) + (fill (quote go)))))) + +(define get-first + (lambda (l) + (call-with-current-continuation + (lambda (here) + (set! leave here) + (waddle l) + (leave (quote ())))))) + + +(start-it2 '((donuts) cheerios (cheerios (spaghettios)) donuts)) +(get-first '(a b c d e f g h i)) ; a +(get-first '(a)) ; a +;(get-next (quote go)) ; error... maybe do many defines +(get-first '((fish) and (chips (chips)))) +;(get-next 'go) + +; i think there might be an error with waddle given +; call-with-current-continuation works... i should try to fix it? + +; well, it works below here, so probably just confused above somwhere + +(define two-in-a-row*? + (letrec + ((T? (lambda (a) + (let ((n (get-next 0))) + (if (atom? n) + (or (eq? n a) (T? n)) + #f)))) + (get-next (lambda (x) + (call-with-current-continuation + (lambda (here-again) + (set! leave here-again) + (fill (quote go)))))) + (fill (lambda (x) x)) + (waddle + (lambda (l) + (cond + ((null? l) (quote ())) + ((atom? (car l)) (let () + (call-with-current-continuation + (lambda (rest) + (set! fill rest) + (leave (car l)))) + (waddle (cdr l)))) + (else (let () + (waddle (car l)) + (waddle (cdr l))))))) + (leave (lambda (x) x))) + (lambda (l) + (let ((fst (call-with-current-continuation + (lambda (here) + (set! leave here) + (waddle l) + (leave (quote ())))))) + (if (atom? fst) (T? fst) #f))))) + +(two-in-a-row*? '(a b c c)) ; #t +(two-in-a-row*? '(((fish) and (chips are) (well) well) what)) ; #t +(two-in-a-row*? '(((fish) and (chips are) (well)) what)) ; #f + +; sweet + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Chapter 20: What's in Store? + +; lots of definitions, just going to throw them out in whatever order + +(define lookup + (lambda (table name) + (table name))) + +; so if the passed value is equal to our name give our value, otherwise +; pass to next in line +(define extend + (lambda (name1 value table) + (lambda (name2) + (cond + ((eq? name2 name1) value) + (else (table name2)))))) + +(define define? + (lambda (e) + (cond + ((atom? e) #f) + ((atom? (car e)) (eq? (car e) (quote define))) + (else #f)))) + +(define *define + (lambda (e) + (set! global-table (extend (name-of e) + (box (The-Meaning (right-side-of e))) + global-table)))) + +(define box + (lambda (it) + (lambda (sel) + (sel it (lambda (new) (set! it new)))))) + +(define setbox + (lambda (box new) + (box (lambda (it set) (set new))))) + +(define unbox + (lambda (box) + (box (lambda (it set) it)))) + +(define The-Meaning + (lambda (e) + (meaning e lookup-in-global-table))) + +(define lookup-in-global-table + (lambda (name) + (lookup global-table name))) + +(define meaning + (lambda (e table) + ((expression-to-action e) + e table))) + +(define *quote + (lambda (e table) + (text-of e))) + +(define *identifier + (lambda (e table) + (unbox (lookup table e)))) + +(define *set + (lambda (e table) + (setbox + (lookup table (name-of e)) + (meaning (right-side-of e) table)))) + +(define *lambda + (lambda (e table) + (lambda (args) + (beglis (body-of e) + (multi-extend (formals-of e) (box-all args) table))))) + +(define beglis + (lambda (es table) + (cond + ((null? (cdr es)) + (meaning (car es) table)) + (else ((lambda (val) + (beglis (cdr es) table)) + (meaning (car es) table)))))) + +(define box-all + (lambda (vals) + (cond + ((null? vals) (quote ())) + (else (cons (box (car vals)) + (box-all (cdr vals))))))) + +(define multi-extend + (lambda (names values table) + (cond + ((null? names) table) + (else + (extend (car names) + (car values) + (multi-extend (cdr names) (cdr values) table)))))) + +(define *application + (lambda (e table) + ((meaning (function-of e) table) + (evlis (arguments-of e) table)))) + +(define evlis + (lambda (args table) + (cond + ((null? args) (quote ())) + (else + ((lambda (val) + (cons val (evlis (cdr args) table))) + (meaning (car args) table)))))) + +(define :car + (lambda (args-in-a-list) + (car (car args-in-a-list)))) + +(define a-prim + (lambda (p) + (lambda (args-in-a-list) + (p (car args-in-a-list))))) + +(define b-prim + (lambda (p) + (lambda (args-in-a-list) + (p (car args-in-a-list) (car (cdr args-in-a-list)))))) + +(define *const + (lambda (e table) + (cond + ((number? e) e) + ((eq? e #t) #t) + ((eq? e #f) #f) + ((eq? e (quote cons)) (b-prim cons)) + ((eq? e (quote car)) (a-prim car)) + ((eq? e (quote cdr)) (a-prim cdr)) + ((eq? e (quote eq?)) (b-prim eq?)) + ((eq? e (quote atom?)) (a-prim atom?)) + ((eq? e (quote null?)) (a-prim null?)) + ((eq? e (quote zero?)) (a-prim zero?)) + ((eq? e (quote add1)) (a-prim add1)) + ((eq? e (quote sub1)) (a-prim sub1)) + ((eq? e (quote number?)) (a-prim number?))))) + +; whew! + +; crap, don't want to have to do a-prim/b-prim every time but +; also avoiding (let ...) for whatever reason + +(define *const + ((lambda (:cons :car :cdr :null? :eq? :atom? :zero? :add1 :sub1 :number?) + (lambda (e table) + (cond + ((number? e) e) + ((eq? e #t) #t) + ((eq? e #f) #f) + ((eq? e (quote cons)) :cons) + ((eq? e (quote car)) :car) + ((eq? e (quote cdr)) :cdr) + ((eq? e (quote eq?)) :eq?) + ((eq? e (quote atom?)) :atom?) + ((eq? e (quote null?)) :null?) + ((eq? e (quote zero?)) :zero?) + ((eq? e (quote add1)) :add1) + ((eq? e (quote sub1)) :sub1) + ((eq? e (quote number?)) :number?)))) + (b-prim cons) + (a-prim car) + (a-prim cdr) + (a-prim null?) + (b-prim eq?) + (a-prim atom?) + (a-prim zero?) + (a-prim add1) + (a-prim sub1) + (a-prim number?))) + +; double whew! + +(define *cond + (lambda (e table) + (evcon (cond-lines-of e) table))) + +(define evcon + (lambda (lines table) + (cond + ((else? (question-of (car lines))) + (meaning (answer-of (car lines)) table)) + ((meaning (question-of (car lines)) table) + (meaning (answer-of (car lines)) table)) + (else (evcon (cdr lines) table))))) + +(define else? + (lambda (x) + (cond + ((atom? x) (eq? x (quote else))) + (else #f)))) + +(define *letcc + (lambda (e table) + (call-with-current-continuation + (lambda (skip) + (beglis (ccbody-of e) (extend (name-of e) + (box (a-prim skip)) + table)))))) + +(define abort) +(define value + (lambda (e) + (call-with-current-continuation + (lambda (the-end) + (set! abort the-end) + (cond + ((define? e) (*define e)) + (else (The-Meaning e))))))) + +; is there any language/interpreter which, when it runs into an undefined +; value, lets you define it on the spot? would be great for learners + +(define the-empty-table + (lambda (name) + (abort (cons (quote no-answer) (cons name (quote ())))))) + +(define expression-to-action + (lambda (e) + (cond + ((atom? e) (atom-to-action e)) + (else (list-to-action e))))) + +(define atom-to-action + (lambda (e) + (cond + ((number? e) *const) + ((eq? e #t) *const) + ((eq? e #f) *const) + ((eq? e (quote cons)) *const) + ((eq? e (quote car)) *const) + ((eq? e (quote cdr)) *const) + ((eq? e (quote null?)) *const) + ((eq? e (quote eq?)) *const) + ((eq? e (quote atom?)) *const) + ((eq? e (quote zero?)) *const) + ((eq? e (quote add1)) *const) + ((eq? e (quote sub1)) *const) + ((eq? e (quote number?)) *const) + (else *identifier)))) + +(define list-to-action + (lambda (e) + (cond + ((atom? (car e)) + (cond + ((eq? (car e) (quote quote)) *quote) + ((eq? (car e) (quote lambda)) *lambda) + ((eq? (car e) (quote letcc)) *letcc) + ((eq? (car e) (quote set!)) *set) + ((eq? (car e) (quote cond)) *cond) + (else *application))) + (else *application)))) + +;leftovers... +(define text-of + (lambda (x) + (car (cdr x)))) +(define formals-of + (lambda (x) + (car (cdr x)))) +(define body-of + (lambda (x) + (cdr (cdr x)))) +(define ccbody-of + (lambda (x) + (cdr (cdr x)))) +(define name-of + (lambda (x) + (car (cdr x)))) +(define right-side-of + (lambda (x) + (cond + ((null? (cdr (cdr x))) 0) + (else (car (cdr (cdr x))))))) +(define cond-lines-of + (lambda (x) + (cdr x))) +(define question-of + (lambda (x) + (car x))) +(define answer-of + (lambda (x) + (car (cdr x)))) +(define function-of + (lambda (x) + (car x))) +(define arguments-of + (lambda (x) + (cdr x))) + +; the right-side-of part is for things like (define stub) +(define global-table the-empty-table) + +(value '(value 1)) +(value '(add1 4)) ; 5 +(value '(define x 7)) +(value 'x) ; 7 +(value '(define even? + (lambda (x) + (cond + ((zero? x) #t) + (else (odd? (sub1 x))))))) +(value '(define odd? + (lambda (x) + (cond + ((zero? x) #f) + (else (even? (sub1 x))))))) +(value '(odd? 3)) ; #t +(value '(odd? 32)) ; slow... but #f! + +; i'm kind of miffed that the (letcc ...) definition basically just uses +; letcc, because magic North Pole compasses seem like the most interesting +; part. + + |