Hello Guilers, Yesterday, I posted this example on IRC ;;; type.scm #!r6rs (library (type) (export define-type) (import (rnrs)) (define-syntax define-type (lambda (stx) (syntax-case stx () [(define-type type-id (field guard) ...) #'(begin (assert (symbol? 'type-id)) (display "yep\n") (define-record-type type-id (protocol (lambda (x) (lambda (field ...) (assert (guard field)) ... (x field ...)))) (fields field ...)))]))) ) ;;; foo.scm (import (type)) ;; not importing (rnrs), because it would hide the bug (define true (lambda _ #t)) (define-type kons (kar true) (kdr true)) (define k1 (make-kons 3 4)) (write k1) I expected this to print yep # but instead I get yep Backtrace: In module/ice−9/boot−9.scm: 170: 8 [catch #t # ...] In unknown file: ?: 7 [catch−closure] In module/ice−9/boot−9.scm: 62: 6 [call−with−prompt prompt0 ...] In module/ice−9/eval.scm: 389: 5 [eval # #] In module/ice−9/boot−9.scm: 2103: 4 [save−module−excursion #] 3535: 3 [#] In unknown file: ?: 2 [load−compiled/vm "/home/Ian/src/guile/cache/guile/ccache/2.0−LE−4−2.0/tmp/foo.scm.go"] In tmp/foo.scm: 6: 1 [#] In unknown file: ?: 0 [# 3 4] ERROR: In procedure #: ERROR: In procedure module−lookup: Unbound variable: assert As you can see, it claims that 'assert' is unbound, but 'yep' gets printed, so the first assert must have been successful (and so must have been bound). Therefore, I came to the conclusion that the protocol expression was not evaluated in the same environment as the define-type macro, but instead the environment of the use i.e. it is non-hygienic. Another example is (let ((immutable #f)) (define-record-type foo (fields (immutable bar))) #t) This should be a syntax error as immutable does not have the same binding as it does in the definition of define-record-type, and therefore we have an invalid field spec, but in guile it is evaluated to #t. I have attached a patch for stable-2.0 to deal with these issues. Keywords are now matched as syntax-case literals, and sub-expressions are de-structured as necessary, rather than by using syntax->datum on all the clauses at the start. There are some issues I didn't touch, e.g. I think that the error messages should be improved, but I can do that too if you would like. If there are any problems let me know, Ian