These clarafications and announcements were originally posted on the assignments page.
(define f '(A iff B)) ; is f a wff? Let's find out! (proposition-wff? f) ;=> #t ; How about some other formuala? (proposition-wff? '(A and ((B iff #t) or C))) ;=> #t ; Of course f could be the formula itself (proposition-wff? 'f) ;=> #t ; We could write procedures to generate formulae too! (proposition-wff? (append f '(not P))) ;=> #f ; oops, (A iff B not P) not a wff
define-syntax
specifies code transformation, not evaluation. All macros are expanded before they are executed. Recursion via define-syntax
can only be on the form of the code, not on runtime values. So the following has a problem:
(define-syntax s (syntax-rules () ((s n) (if (= n 0) 'done (s (- n 1)))))) (s 1) ; expands to ; (if (= 1 0) 'done (s (- 1 1))) ; expands to ; (if (= 1 0) 'done ; (if (= (- 1 1) 0) 'done (s (- (- 1 1) 1)))) ; expands to ; (if (= 1 0) 'done ; (if (= (- 1 1) 0) 'done ; (if (= (- (- 1 1) 1) 0) 'done (s (- (- (- 1 1) 1) 1))))) ; etc.
If you want the transformed code to execute recursively, produce standard recursive code (involving letrec
, named let
, etc).
(define-syntax for (syntax-rules (in) ((_ v in l body ...) '(for-each (lambda (v) body ...) l)))) (for i in '(1 2 3) (display i) (newline)) => (for-each (lambda (i) (display i) (newline)) (quote (1 2 3)))
Note that if you have recursive rules, this will only show one level of expansion. Also, if the result is big, you might want to pretty-print
it:
(require (lib "pretty.ps")) ; not so exciting, but it would be for big examples. (pretty-print (for i in '(1 2 3) (display i) (newline)))
(define-syntax ++ (syntax-rules () ((_ var) (begin (set! var (+ 1 var)) var)))) (define x 1) (++ x) xNotice that var is just text replaced by x in the expansion. We could generalize this to let ++ apply to a list of variables, and return the incremented value of the last variable:
(define-syntax ++ (syntax-rules () ((_ vars ... lastvar) (begin (set! vars (+ 1 vars)) ... (set! lastvar (+ 1 lastvar)) lastvar)))) (let ((a 1) (b 10) (c 100)) (++ a b c) a b )The ... in the syntax rule matches 0 or more expressions, so when we mention vars in the expansion, and then use ... sometime after it, it will be repeated once for each expression that matched vars.
(define Coloured-Point (class (colour x y) (super (Point x y)) ((colour get colour)) ((equal? p) (and (super 'equal? p) (equal? colour (p 'colour))))))
|