;;;;;;;;;;;;;;;;;; ;; introduction ;; ;;;;;;;;;;;;;;;;;; ; make-adder (define (make-adder n) `(lambda (d) (+ d ,n))) ; twice macro (define-macro (twice expr) (list 'begin expr expr)) ;;;;;;;;;;;;;;;;;;;;;; ;; while statements ;; ;;;;;;;;;;;;;;;;;;;;;; ; sum-while with too many procedure calls (define (sum-while-proc init condn expr nxt) (begin (define (f x total) (if (condn x) (f (nxt x) (+ total (expr x))) total)) (f init 0))) ; a sample piece of code that can use the above sum-while (sum-while-proc 2 (lambda (x) (< x 10)) (lambda (x) (* x x)) (lambda (x) (+ x 2))) ; sum-while with not quite as many procedure calls (define (sum-while init condn expr nxt) `(begin (define (f x total) (if ,condn (f ,nxt (+ total ,expr)) total)) (f ,init 0))) ; a sample piece of code that can use the above sum-while (eval (sum-while 2 '(< x 10) '(* x x) '(+ x 2))) ; sum-while macro (define-macro (sum-while-macro init condn expr nxt) `(begin (define (f x total) (if ,condn (f ,nxt (+ total ,expr)) total)) (f ,init 0))) ; a sample piece of code that can use the above sum-while (sum-while-macro 2 (< x 10) (* x x) (+ x 2)) ;;;;;;;;;;;;;;;;;;;;;;;;; ;; checking truthiness ;; ;;;;;;;;;;;;;;;;;;;;;;;;; ; the not-so-useful check procedure (define (check val) (if val 'passed 'failed)) ; sample usage (check (> x 0)) ; the much-more-useful check procedure (define (check expr) `(if ,expr 'passed '(failed: ,expr))) ; sample usage (eval (check '(> x 0))) ; the check macro (define-macro (check expr) `(if ,expr 'passed '(failed: ,expr))) ; sample usage (check (> x 0)) ;;;;;;;;;;;;;;;;;;;; ;; for statements ;; ;;;;;;;;;;;;;;;;;;;; ; map takes in a list of VALS and applies FN to all of them (define (map fn vals) (if (null? vals) () (cons (fn (car vals)) (map fn (cdr vals))) )) ; squares all the values in '(2 3 4 5) (map (lambda (x) (* x x)) '(2 3 4 5)) ; the for macro makes the above syntax a bit cleaner (define-macro (for var vals expr) `(map (lambda (,var) ,expr) ,vals) ) ; squares all the values in '(2 3 4 5) (for x '(2 3 4 5) (* x x)) ; this for macro does the same thing without quasiquotes (define-macro (for-list var vals expr) (list 'map (list 'lambda (list var) expr) vals) ) ; squares all the values in '(2 3 4 5) (for-list x '(2 3 4 5) (* x x)) ; this for macro makes the quote before '(2 3 4 5) unnecessary ; this is also unnecessarily complicated, and you should not ; look to it as something that you should fully understand (define-macro (for-vals var vals expr) `(map (lambda (,var) ,expr) ',vals) ) ; squares all the values in '(2 3 4 5) (for-vals x (2 3 4 5) (* x x)) ;;;;;;;;;;;;;;;;;;;;;;;; ;; fall 2019 final q9 ;; ;;;;;;;;;;;;;;;;;;;;;;;; ; creates a procedure from a partial call expression missing the last operand (define-macro (partial call) `(lambda (y) ,(append call (list 'y))) ) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; spring 2019 final q8 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;; ; implements the if special form using only and/or. what's wrong? (define-macro (if condition then else) `(or (and ,condition ,then) ,else) ) ; implements the if special form using only and/or/not. what's wrong? (define-macro (if condition then else) `(or (and ,condition ,then) (and (not ,condition) ,else)) )