simpler-macros-examples


The following are simpler-macros versions of the example macros given in syntactic-closures.

The swap! macro can easily be done in simpler-macros as follows:

 (define-syntax (swap! a b) 
   (quasisyntax 
    (let ((temp ,a))  
      (set! ,a ,b)  
      (set! ,b temp)))) 

A syntax objects is here constructed hygienically a quasisyntax template. Inserted syntactic elements have to be unquoted, since there is no primitive concept of pattern variables, which makes the design conceptually simpler than that of syntax-case. Indeed, pattern matching is not necessary for the core design, although syntax-case is provided as a separate module.

For the loop macro, we need to break hygiene. For this, datum->syntax-object is available with the same semantics as in syntax-case. Instead, we use an alternative mechanism make-fluid-identifier as follows:

 (define-syntax (loop body)  
   (let ((exit (make-fluid-identifier (syntax here) 'exit))) 
     (quasisyntax  
      (call-with-current-continuation 
       (lambda (,exit)               
         (let loop ()  
           ,body  
           (loop))))))) 

The make-fluid-identifier primitive introduces an identifier that will capture any free-identifier=? identifiers in the scope of its binding. The first argument provides the lexical context of the manufactured identifier.

We do the same thing with the it identifier for the aif macro. To control the precise scope of it within the macro, we use ordinary lexical scope via let, just as you would in an ordinary Scheme procedure.

 (define-syntax (aif condition consequent alternative) 
   (let ((it (make-fluid-identifier (syntax here) 'it))) 
     (quasisyntax 
      (let ((val ,condition))  
        (if val 
            (let ((,it val)) ,consequent) 
            ,alternative))))) 

category-syntax category-macro