-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hygienic macro syntax-rules #43
Comments
syntax-rules to transform (a b ...) on single item fix repr of (cons 1 undefined)
This macro don't work: (define-syntax for
(syntax-rules (in as)
((for element in list body ...)
(map (lambda (element)
body ...)
list))
((for list as element body ...)
(for element in list body ...))))
(for '(0 1 2 3 4) as i
(print i)) Because identifiers are not used to match the pattern. The code try to match first pattern so element is a list. |
|
Example that don't work (taken from SRFI 46) (let-syntax
((f (syntax-rules ()
((f ?e)
(let-syntax
((g (syntax-rules ::: ()
((g (??x ?e) (??y :::))
'((??x) ?e (??y) :::)))))
(g (1 2) (3 4)))))))
(f :::)) it should return |
throw exception when invoking syntax that shadow literal identifier
SRFI 46 example works. |
The problem was identifiers definition get expanded into values from parent syntax-rules
Fix case when there is list and first item in user code is nil When the user code is in ellipsis processing and there is next item There is need to be list where first item need to be nil.
Two examples that should work: (define-syntax foo (syntax-rules () ((_ x ...) #(x ...))))
(define-syntax foo (syntax-rules () ((_ #(x y ...)) x))) There is need to add vector support to syntax-rules. |
Another use case nested ellipsis from practical-scheme.net. (define-syntax ellipsis-test
(syntax-rules ()
[(_ (a (b c ...) ...) ...)
'((a ...)
(((a b) ...) ...)
((((a b c) ...) ...) ...))]))
(ellipsis-test (1 (2 3 4) (5 6)) (7 (8 9 10 11)))
;; ⇒ ((1 7)
;; (((1 2) (1 5)) ((7 8)))
;; ((((1 2 3) (1 2 4)) ((1 5 6))) (((7 8 9) (7 8 10) (7 8 11))))) NOTE: this is not part of R7RS, can be implemented later. |
While debugging SRFI-197 macro, found another example that doesn't work: (define-syntax foo
(syntax-rules ()
((_)
(let ()
(define-syntax %foo
(syntax-rules (foo bar)
((_ (foo))
(display "foo"))
((_ x)
(display 'x))))
(%foo (10))))))
(foo) should print This one case can be fixed by not matching the first expression in the pattern to identifiers. Also this: (define-syntax foo
(syntax-rules ()
((_)
(let ()
(define-syntax %foo
(syntax-rules (foo bar)
((__ (foo))
(print '(foo)))
((__ x)
(print 'x))))
(%foo (foo))))) prints: |
The problem with SRFI-210 is not about hygiene: This works fine: (define-syntax foo
(syntax-rules ()
((_ () ((operand1 arg1) ...))
(let ((arg1 operand1) ...)
(list arg1 ...)))
((_ (operand1 operand2 ...) (temp ...))
(foo (operand2 ...) (temp ... (operand1 arg1))))))
(pprint (macroexpand (foo (10 20) ())))
;; (#:let ((#:arg1 10)
;; (#:arg1 20))
;; (#:list #:arg1 #:arg1))
(print (foo (10 20) ()))
;; => (10 20) |
The problem was that identifiers in |
Another problem found from SRFI-210 is this macro: (define-syntax foo
(syntax-rules ()
((_ (arg more ...))
(letrec-syntax ((aux (syntax-rules ::: ()
((aux () ((operand1 arg1) :::))
(let ((arg1 operand1) :::)
(list arg1 :::)))
((aux (operand1 operand2 :::) (temp :::))
(aux (operand2 :::) (temp ::: (operand1 arg1)))))))
(aux (arg more ...) ())))))
(print (foo (10 20)))
;; ==> (20 20) Same code with single a |
This is the limitation of renaming The whole syntax-rules need to be refactored into a proper scope based system. |
Fix case with spread and tail (x ... . x) matched against (x y . z)
Hygienic macro syntax-rules
(x ... ...)
List of issues
(_ () var1 ... var2)
#244The text was updated successfully, but these errors were encountered: