This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

macros and the module system


Hi,

This is maybe a well-known problem. Maybe somebody knows an easy solution for 
it that can be used while Estragon is still here ...

I find the way define-syntax in (ice-9 syncase) and the module system interact 
very unintuitive. Whenever a macro that is exported from a module uses a 
private variable in its body, the use of the macro leads to a unbound-variable 
error. The code at the end of the message illustrates that.

As far as I understand R5RS, free variables that the transformer introduces have to be bound in the env of the macro _definition_, not the env of the _expansion_.

I know that guile is not R5RS yet, but I would be really curious to know if there is a good workaround for this; at the moment I just export what's used in the macro body (or use define-macro instead of define-syntax, if it doesn't cause too much headache) 

Thanks,
David

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; File modmac.scm
(define-module (macros))
(export-syntax mac-public syntax-public)
(use-modules (ice-9 syncase))

(define private 'private-val)

;; use private with simple define-macro
(define-macro (mac-public arg)
  (write (list 'done-mac-public private arg)))

;; R5RS says that free names introduced by the transformer
;; have to be bound in the environment in which the macro
;; is _defined_, so this should work (Do I understand R5RS right?)
(define-syntax syntax-public
  (syntax-rules ()
    ((syntax-public args)
     (write (list 'done-syntax-public private 'args)))))

;; Everything is fine and dandy when we expand in the
;; same module
(display "\n** Inside module:\n")
(mac-public inside)
(newline)
(syntax-public inside)
(newline)

;;; Now in a new module
(define-module (test))
(use-modules (macros))
(display "\n** Outside module:\n")
(mac-public outside)			; This works
(newline)
(syntax-public outside)		; This doesn't: mac-private is unbound
(newline)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Output from guile:
** Inside module:
(done-mac-public private-val inside)
(done-syntax-public private-val inside)

** Outside module:
(done-mac-public private-val outside)