-
Notifications
You must be signed in to change notification settings - Fork 143
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
Implement datum->syntax for explicitely renamed identifiers #496
Conversation
Thanks very much for the investigation and patch! This is perhaps the most obvious approach, and I believe was proposed at one time by Taylor Campbell and possibly implemented in his riaxpander. Another approach involves a hybrid of (or switch to) counters. I want to think a little about this before merging since it's a fairly heavy-handed approach. |
I have to apologize if this approach had been proposed before and I didn't acknowledge it because I didn't know of prior discussions of this problem. When I discovered the problem for myself, I was surprised that all descriptions/advertisements of Thinking about the patch before merging sound very reasonable. For example, one can ask what the meaning of the What do you mean by counters? That a colored identifier is just a symbol together with a counter and that the counter is increased for any instantiation of any macro? This sounds like a cut-down version of the marks and substitutions algorithm by Dybvig and Hieb, right? Whatever the short-time fix for the issue is, it would be nice if the underlying macro system of Chibi would become powerful enough to implement even Maybe one can take a look at the implementation of SRFI 72, which I haven't yet, though. I think this is also the implementation used by Larceny. |
Hello. I tried to add datum->syntax to Gauche. But I was pointed out that
This solution needs an identifier in macro which uses 'failure'. I have no idea to workaround for this case. Though, I report this for information sharing. |
Hamayama, the reason why your example doesn't work is that Could you briefly explain what your post has to do with my proposed addition to Chibi? Note that Chibi does not have |
Umm, I know 'divide' can be written by er-macro and datum->syntax. if divide2 doesn't exist, wrapper works well. From end-user view, divide and divide2 are the same interface. |
Assume that So it is not a problem of If you want to create a true wrapper for (define-syntax divide2 (identifier-syntax divide)) |
P.S.: The So, your example applied to SRFI 99 would be something like the following: (let-syntax
((wrapper
(syntax-rules ()
((wrapper1 record)
(define-record-type record #t #t))
((wrapper2)
(wrapper1 record)
(record? (make-record)))))
(wrapper1)) This example (legatimately) fails because the identifiers that |
Uhm, I understood what you say ... But datum->syntax used in library (such as SRFI 99) introduces To avoid confusion, We should pass arguments to syntax-rules explicitly, shoudn't we? (But if specification of library (such as SRFI 99) is well documented, datum->syntax might be useful ... |
Convincing use cases for unhygienic macros are few in my opinion. For example, to achieve what the (define-syntax-parameter failure (syntax-rules ()))
(define-syntax divide
(syntax-rules ()
((divide x y)
(if (zero? y) (failure) (/ x y)))))
(define-syntax divide2
(syntax-rules ()
((divide2 x y)
(divide x y))))
(define-syntax wrapper
(syntax-rules ()
((wrapper)
(let ((f (lambda () (display "division by zero") (newline))))
(syntax-parameterize ((failure (identifier-syntax f))) ;Or use syntax rules.
(divide2 1 0))))))
(let ()
(wrapper)) There is, however, one legitimate use case of unhygienic macros, namely the one of SRFI 99. It mainly saves the user from writing down the derived names And if one wanted to implement the module system of the R7RS as a macro itself, one would also need this kind of unhygiene to implement the |
Thank you for detailed explanation. |
…he implementation of SRFI-99
073e449
to
ce49264
Compare
@ashinn Before you merge this branch, please wait for my next pull request. I managed to implement the |
This also fixed the implementation of SRFI-99, see issue #494.
Some unhygienic macros (like define-record-type of SRFI 99 when the constructor or predicate name is not given explicitly) need to create identifiers that behave as if they were present in the input form. The following example is from Chicken's description of
er-macro-transformer
:Here,
exit
is not renamed as it shall beeq?
to the identifier with the same name where theloop
macro is called. However, by issue #494, this macro behaves incorrectly in some sense. Whenloop
is called in the instance of another (hygienic) macro, the identifierexit
of the instance may be renamed, while the identifierexit
introduced byloop
refers to the uncolored identifier of the nameexit
.The conclusion is that one cannot write robust unhygienic macros with
er-macro-transformer
alone. What is missing is something like the(datum->syntax id datum)
expression of the R6RS, which takes an identifierid
and a datumdatum
representing an expression and turnsdatum
into a syntax object (an expression that contains syntactic closures (of identifiers)) that behaves as if introduced whereid
was introduced. The corrected loop macro would be:This patch does the following to implement
datum->syntax
:rename
, which is#f
initially.er-macro-transformer
creates identifiers (as syntactic closures), it stores itsrename
procedure in therename
field of the created identifier.(symbol->identifier id sym)
is defined, whereid
is an identifier andsym
is a symbol. Ifid
is a syntactic closure,sym
is being renamed using therename
procedure stored inid
; otherwisesym
is returned unchanged.datum->syntax
just recursively appliessymbol->identifier
to each symbol occurring in the expression datum.