42 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			42 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| (define-syntax color (syntax-rules () ((color) 'green)))
 | |
| 
 | |
| (define-syntax with-blue
 | |
|   (lambda (exp r c)
 | |
|     `(,(r 'let-syntax) ((color (,(r 'syntax-rules) ()
 | |
|                                  ((color) 'blue))))
 | |
|        . ,(cdr exp))))
 | |
| 
 | |
| (with-blue (color))
 | |
| 
 | |
| ;;; This has a problem --  WITH-BLUE is not hygenic:
 | |
| (let ((color (lambda () 'foo)))
 | |
|   (with-blue (color)))
 | |
| 
 | |
| => blue
 | |
| 
 | |
| ;;; Let's fix this by adding a layer of indirection --
 | |
| ;;; 1. (color) ==> (hidden-color)
 | |
| ;;; 2. with-blue frobs the definition of *our* hidden-color
 | |
| 
 | |
| (define-syntax hidden-color (lambda (exp r c) `(,(r 'quote) green)))
 | |
| (define-syntax color        (lambda (exp r c) `(,(r 'hidden-color))))
 | |
| 
 | |
| (define-syntax with-blue
 | |
|     (lambda (exp r c)
 | |
|       `(,(r 'let-syntax) 
 | |
|             ((,(r 'hidden-color) (,(r 'syntax-rules) ()
 | |
|                                    ((,(r 'hidden-color)) (,(r 'quote) blue)))))
 | |
| 	. ,(cdr exp))))
 | |
| 
 | |
| ;;; Without all the renaming, the above is
 | |
| ;;; (let-syntax ((hidden-color (syntax-rules () ((hidden-color 'blue)))))
 | |
| ;;;   body ...)
 | |
| ;;; where *all* symbols on the first line are renamed, *including* 
 | |
| ;;; hidden-color, so we should be redefining the same hidden-color
 | |
| ;;; to which (color) expands.
 | |
| 
 | |
| ;;; It doesn't work:
 | |
| (with-blue (color))
 | |
| => green
 | |
| 
 |