[R6RS] new syntax srfi draft, reference implementation

dyb at cs.indiana.edu dyb at cs.indiana.edu
Thu May 18 11:37:05 EDT 2006

> > Through constructed programs that are passed to eval and constructed
> > syntax objects returned by transformers.  The issue can also arise in
> > other ways, such as through the #n= and #n# syntax, in particular
> > implementations (and possibly in future reports).
> I know it's a detail question, but does that mean non-datums can arise
> from macro expansion?  I.e., could I quote the unspecified value by
> plugging it in a quote as part of macro expansion like so:
> (with-syntax ((un (unspecified)))
>   (syntax (quote un)))

Actually, that's a good question.  Allowing such things causes no problems
in the expander, but it can cause problems downstream, especially for
separate compilation, if the inserted value has no printed representation. 
We should decide if quote "must/should/may/might" raise an exception if
the x in (quote x) is not a datum.  I'm inclined to say "should";
otherwise, implementations will be required to perform a general graph
cycle check, which is much more onerous than the simple tortoise-and-hare
algorithm for lists.

> No, a macro might expand into a definition.  Is that macro fully
> expanded, or only to the point where it is evident it is a definition?
> If only to that point, that's in conflict with the above quote.  In
> either case, that needs to be spelled out.

Are you thinking that invoking a transformer results in a complete
recursive expansion of the form down to core forms?  That's not the case. 
A transformer performs its transformation, then returns without
recursively expanding the result.  (Perhaps the word "expand" in "invokes
the associated transformer to expand the syntactic abstraction" is
misleading.  I've replaced it with "transform".)

In the example given at the end of Section 3.1, when the defun transformer
is invoked on the second form,

  (defun (even? n) (or (= n 0) (odd? (- n 1))))

the transformer transforms it to

  (define even? (lambda (n) (or (= n 0) (odd? (- n 1)))))

The expander recognizes this as a definition, skips the RHS expression,
and proceeds to the next form.  Once the last form is determined to be an
expression, it and the skipped RHS expression are expanded.  Nothing is
expanded twice, and there is no revisiting of any source expression; the
expansion is just done in a particular order, as if the expander processes
the definitions to construct a letrec* form, then expands its

> >> - In Section 3.4, first paragraph: What exactly is a "keyword
> >>   reference"?
> >
> > A reference to a keyword, i.e., an identifier reference that resolves to a
> > keyword.
> I still don't get it---do you mean that it is a syntax object
> representing an identifier that is a keyword?

I think missed the point of your original question, which is probably that
the nature of the actual transformer argument isn't clear.  I've edited
the text to say that the transformer receives "a wrapped syntax object
representing just the keyword reference".

> > I would say not, unless we're also going to require similarly more robust
> > versions of let and other derived forms.
> But we are requiring that, no?

At some level, a check should be made, but I think I prefer to allow an
implementation to write let as follows

  (define-syntax let
    (syntax-rules ()
      [(_ ((x e) ...) b1 b2 ...)
       ((lambda (x ...) b1 b2 ...) e ...)]
      [(_ f ((x e) ...) b1 b2 ...)
       ((letrec ([f (lambda (x ...) b1 b2 ...)]) f) e ...)]))

and have lambda report any non-identifier or duplicate-identifier errors. 
This seems like a quality-of-implementation issue and not something we
have to dictate.


More information about the R6RS mailing list