Hi Ludovic, [email protected] (Ludovic Courtès) writes:
> Mark H Weaver <[email protected]> skribis: > >> In the end, here's how this works: 'with-ellipsis' binds a special >> identifier named #{ $sc-ellipsis }# using a new 'ellipsis' binding type. >> The new ellipsis identifier is stored within the binding. In order to >> determine whether an identifier X is an ellipsis, the binding for >> #{ $sc-ellipsis }# is looked up in the lexical environment of X. If the >> binding is found and has binding-type 'ellipsis', then X is compared to >> the identifier stored in the binding using 'bound-id=?'. Otherwise, X >> is compared to '...' using 'free-id=?' as was done before. > > This looks nice! Thanks for providing the detailed reasoning, that’s > insightful. > > Does something like this work: > > (define-syntax define-inline > (with-ellipsis --- > (syntax-rules () > ((_ (name parms ---) exp ---) > (define-syntax name > (syntax-rules () > ((_ args (--- ---)) > ((lambda (parms ---) exp ---) > args (--- ---))))))))) No, because as noted in the docs, the custom ellipsis does not propagate to the generated code. Therefore, given the above definition, (define-inline (foo a b c) (list a b c)) expands to: (define-syntax foo (syntax-rules () ((_ args ---) ((lambda (a b c) (list a b c)) args ---)))) However, '---' is not the ellipsis identifier for this generated macro, because the 'with-ellipsis' is not present in the generated code. Therefore, '---' is treated as a normal pattern variable by the generated macro. It is important that the custom ellipsis does not propagate to the generated code, so that we can use 'with-ellipsis' to implement R7RS 'syntax-rules', which allows a custom ellipsis as its first operand, before the literals list. In R7RS 'syntax-rules', the custom ellipsis does not propagate to generated code. A corrected version of your macro is the following: (define-syntax define-inline (with-ellipsis --- (syntax-rules () ((_ (name parms ---) exp ---) (define-syntax name (syntax-rules () ((_ args ...) ((lambda (parms ---) exp ---) args ...)))))))) Note that as currently implemented, the effect of 'with-ellipsis' also does not propagate into nested syntax definition forms such as 'let-syntax', 'letrec-syntax', and 'define-syntax'. We could go either way on this. I confess that I didn't make this decision intentionally. It was an accident of the current implementation. The reason is that transformer expressions are evaluated in a "macros only" environment, with all other bindings removed (see 'macros-only-env' in psyntax.scm). We could arrange to keep the ellipsis binding in that restricted environment as well, if desired. I don't think it matters much. What do you think? > Could you wrap lines to 80 columns in psyntax.scm? Ordinarily I try to keep lines to 80 columns, but psyntax.scm already has a great deal of code that violates that rule. Fixing that would be a rather large commit, and I'm not sure it would be an improvement. >> +@subsubsection Specifying a custom ellipsis identifier > > Should be “Specifying a Custom Ellipsis Identifier”. > >> +@subsubsection Custom ellipsis identifiers for syntax-case macros > > Likewise. Okay. Thanks! Mark
