I've heard er macro and syntax-case can do the same things (or they have almost the equal power). Now I'm wondering if this is really true or not. Once upon a time, there was an R6RS portable OOP library called nausicaa-oopp. For some reason its repository is removed from GitHub. The library used syntax-case to its limit (I think) and provided CL like multi method and other OOP things.
One of the remarkable thing of the library was it inserts identifiers which renamed by
syntax-case
or syntax
and binds a macro to it, then inside of the macro it refers the original identifier. For example, it can do like this thing:;; <beta> is a macro which represents a class of object o. ;; with-tags binds a macro which name is o, thus the o in its body ;; refers to the macro. however inside of the macro o, it refers ;; given o. (define (beta-def-ref o) (with-tags ((o <beta>)) (list (o d) (o e) (o f))))If you just read the comment, it seems pretty much normal thing however the macro
with-tags
requires to have the same name as the o passed to beta-def-ref
. Thus this would raise an error.
(define (beta-def-ref o) (with-tags ((oo <beta>)) (list (oo d) (oo e) (oo f))))Can this be done on er macro? The answer is yes. This is the piece of code: https://gist.github.com/ktakashi/63745cf1b7e0a018b64f
Then how portable is this? I know there is no concrete specification of er macro so I would expect this type of code may not be portable. So I've run it on Chicken, Chibi, Gauche and Sagittarius. And the following is the result:
Chicken: dispatched! dispatched! dispatched! (a a a) dispatched! dispatched! dispatched! Error: unbound variable: oo Call history: <eval> (cdr2441 x2345) <eval> (pair?2514 x2440) <eval> (null?2515 (cdr2516 x2440)) <eval> (cdr2516 x2440) <eval> (car2519 x2440) <eval> (pair?2536 w2518) <eval> (car2539 w2518) <eval> (cdr2541 w2518) <eval> (display (quote dispatched!)) <eval> (newline) <eval> (r src) <syntax> (beta-def-ref2 (quote a)) <syntax> (quote a) <syntax> (##core#quote a) <eval> (beta-def-ref2 (quote a)) <eval> [beta-def-ref2] (list2684 (oo2680 d2685) (oo2680 e2686) (oo2680 f2687)) <-- Chibi: dispatched! dispatched! dispatched! (a a a) dispatched! dispatched! dispatched! ERROR in beta-def-ref2: undefined variable: oo called from <anonymous> on line 1039 of file /home/takashi/sandbox/share/chibi/init-7.scm called from <anonymous> on line 542 of file /home/takashi/sandbox/share/chibi/init-7.scm called from <anonymous> on line 622 of file /home/takashi/sandbox/share/chibi/init-7.scm Searching for modules exporting oo ... ... none found. Gauche: dispatched! dispatched! dispatched! *** ERROR: unbound variable: o While loading "./er.scm" at line 154 Stack Trace: _______________________________________ 0 o 1 (beta-def-ref 'a) At line 154 of "./er.scm" Sagittarius: dispatched! dispatched! dispatched! (a a a) dispatched! dispatched! dispatched! Unhandled exception Condition components: 1. &undefined 2. &who oo 3. &message unbound variable oo in library user stack trace: [1] beta-def-ref2 src: (lambda (o) (with-tags ((oo <beta>)) (list (oo d) "er.scm":157 [2] loadChicken, Chibi and Sagittarius worked as I expected. It seems Gauche can't resolve the original binding.
import-for-syntax
resolves this. Thanks evhan!During writing the code, I've notice a small thing. Chibi and Chicken accepts the following:
(define-syntax foo (er-macro-transformer (lambda (f r c) (r '(display "hoge"))))) (foo) ;;-> prints "hoge"However Gauche and Sagittarius raise an error. As a user, it's convenient if I can rename a list with rename procedure but is this actually common in sense of er macro?
No comments:
Post a Comment