; Syntactic extension examples - see chapter 3 ; I have commented that Scheme has "syntactic sugar", that is ; expressions that are really just syntactic forms for other Scheme ; language features, like lambda expressions. These are defined ; using "syntactic extensions" in Scheme, which is an example ; of a "macro" language. ; IF using GNU guile, uncomment the following line to ; load the syntax case module ;(use-syntax (ice-9 syncase)) ; We write the syntactic extension using one or more ; patterns matching the different expression forms (define-syntax and (syntax-rules () ((_) #t) ;; (and) ((_ e) e) ;; (and e) ((_ e1 e2 e3 ...) ;; (and e1 e2 e3 ...) (if e1 (and e2 e3 ...) #f)))) ; or is a bit more complicated, because anything ; other than #f is considered a true value (define-syntax or (syntax-rules () ((_) #f) ;; (or) ((_ e) e) ;; (or e) ((_ e1 e2 e3 ...) ;; (or e1 e2 e3 ...) (let ((t e1)) (if t t (or e2 e3 ...)))))) ; As we have seen before, the unnamed "let" is really ; syntactic sugar for a lambda expression. Try modifying ; this macro to allow a named let. Hint: use a letrec. (define-syntax let (syntax-rules () ((_ () e1 e2 ...) ((lambda () e1 e2 ...))) ((_ ((x v) ...) e1 e2 ...) ((lambda (x ...) e1 e2 ...) v ...)))) (define-syntax let* (syntax-rules () ((_ () e1 e2 ...) (let () e1 e2 ...)) ((_ ((x v) (y z) ...) e1 e2 ...) (let ((x v)) (let* ((y z) ...) e1 e2 ...))))) ; Example usage: ; (define x 5) ; (let ((x 1) (y x)) (+ x y)) ; (let* ((x 1) (y x)) (+ x y)) ; We can also define new operators. For example, ; we might define C-like unary preincrement ; and predecrement (define-syntax ++ (syntax-rules () ((_) 1) ((_ e) (+ e 1)))) (define-syntax -- (syntax-rules () ((_) -1) ((_ e) (- e 1)))) ; HOMEWORK: Implement an "xor" operator ; using a syntactic extension