#lang racket (define TRUE (lambda (x y ) x)) (define FALSE (lambda (x y) y)) ; with TRUE and FALSE defined this way, we actually can implement ; if without cheating. Note how the logical value selects the ; wrapping lambda to be evaluated, and then the evaluation occurs. (define-syntax-rule (lif condition consequent alternate) ( (condition (lambda () consequent) (lambda () alternate)) ) ) ; as well as the other logical operations. (define-syntax-rule (land a b) (a b a)) (define-syntax-rule (lor a b) (a a b)) (define-syntax-rule (lnot a) (a FALSE TRUE)) (define-syntax-rule (lxor a b) (a (b FALSE TRUE) b)) (lxor TRUE TRUE) (lxor TRUE TRUE) (define a TRUE) (define b FALSE) (lif (land a b) (print "1") (print "0")) ; further exploting the macro capability we can introduce the ; extended version of and and or that take 0 or more arguments and ; short-circuit evaluation (define-syntax lland (syntax-rules () [(lland) TRUE] ; no arguments, TRUE is identity for and [(lland a) a] [(lland a b ...) (a (lland b ...) FALSE) ] )) (define-syntax llor (syntax-rules () [(llor) FALSE] [(llor a) a] [(llor a b ...) (a TRUE (llor b ...)) ] )) (lland TRUE FALSE TRUE)