cisco / ChezScheme

Chez Scheme
Apache License 2.0
6.97k stars 986 forks source link

Macro don't expand properly if wrapped inside a library #93

Closed ovenpasta closed 8 years ago

ovenpasta commented 8 years ago

Hello, It's not the first time I have problems with wrapping macros inside libraries. Here is a simple example that is happening lastly:

https://github.com/ovenpasta/thunderchez/blob/master/srfi/s26/cut.scm If I load this with (load "cut.scm") or (include "cut.scm") it is behaving properly:

> (include "srfi/s26/cut.scm")
> ((cut list <> 1) 0)
(0 1)
> (sc-expand '(cut list <> 1))
(lambda (#{x dmn0455oaiyb5qpdyyw6v5-0})
  (#2%list #{x dmn0455oaiyb5qpdyyw6v5-0} 1))

Instead if use the wrapped code inside the library: https://github.com/ovenpasta/thunderchez/blob/master/srfi/s26/cut.sls


> (import (srfi s26 cut))
> ((cut list <> 1) 0)
Exception: incorrect argument count in call ((lambda () (list <> 1)) 0)
Type (debug) to enter the debugger.
> (sc-expand '(cut list <> 1))
(lambda () (#2%list <> 1))

Best regards

jltaylor-us commented 8 years ago

The auxiliary keyword identifiers (<> and <...>) must be exported from the library if they're ever going to match an identifier from outside the library. This behavior is not entirely obvious, but it is implied by the documentation for syntax-rules and free-identifier=?

ovenpasta commented 8 years ago

I've tried adding <> and <...> to the exports... but....

> (import (srfi s26 cut))
Exception: missing definition for multiple exports, including <...> at line 9, char 23 of /home/aldo/thunderchez/srfi/s26/cut.sls
Type (debug) to enter the debugger.
akeep commented 8 years ago

Yep, you also need to add some kind of syntactic binding for these. You can do this with something like:

(define-syntax <>
  (lambda (x)
    (syntax-violation #f "misplaced use of auxiliary keyword" x)))

I have a couple of handy macros I use for this in the nanopass framework:

  (define-syntax define-auxiliary-keyword
    (syntax-rules ()
      [(_ name)
       (define-syntax name 
         (lambda (x)
           (syntax-violation 'name "misplaced use of auxiliary keyword" x)))]))

  (define-syntax define-auxiliary-keywords
    (syntax-rules ()
      [(_ name* ...)
       (begin (define-auxiliary-keyword name*) ...)]))

Then you can do something like:

(define-auxiliary-keywords <> <...>)
ovenpasta commented 8 years ago

thank you! now it works properly ;)

bjoli commented 7 years ago

For future reference if anyone stumbles across this: if you have two modules both using <> and <...> you can't have both export their own version of it.

You will have to define them in one module, and then have the other import and re-export them.