[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Suggestions and EIOD update



At http://petrofsky.org/src I've put an updated version of EIOD that
supports the SRFI-46 draft.  At the same location you can find
alexpander, which also supports the current draft.

Some comments on the SRFI:

  ELLIPSIS-IDENTIFIER specifies the token used for ellipsis.  ... This
  identifier, when generated by macros, is subject to the usual rules
  of hygiene.

That's pretty vague.  I realize that all descriptions of r5rs macro
hygiene are a bit vague (the earlier formal treatments done by
Kohlbecker and later Clinger don't address the macro-writing-macros
capabilities that ended up in r5rs), and it's reasonable not to try to
make this SRFI any more rigorous than r5rs, but I think the statement
above is still a little too vague.  Also, it's crucial, in the absence
of rigor, that you at least include an example or two showing some of
the consequences of what you are informally describing.

The r5rs rules of hygiene are (from r5rs 4.3):

  All macros defined using the pattern language are "hygienic" and
  "referentially transparent" and thus preserve Scheme's lexical
  scoping:

   * If a macro transformer inserts a binding for an identifier
     (variable or keyword), the identifier will in effect be renamed
     throughout its scope to avoid conflicts with other identifiers.
     Note that a define at top level may or may not introduce a
     binding; see section 5.2.

   * If a macro transformer inserts a free reference to an identifier,
     the reference refers to the binding that was visible where the
     transformer was specified, regardless of any local bindings that
     may surround the use of the macro.

These "usual rules" don't say anything about ellipses.  I think the
minimal way to state what you are getting at (assuming that what you
are trying to say is what I implemented) is something like this:

  When an ellipsis identifier is specified, that specification is
  considered a binding whose scope is the rules of the transformer.
  The macro system must make the usual hygienic arrangements to
  preserve the lexical scoping of these bindings.

Here's an example you could use, whose result depends on whether or
not F inserts the binding for ::: hygienicly:

  (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 :::))
  => ((1) 2 (3) (4))    [ rather than ((1) (2) (3) (4)) ]

I think the "tail patterns" feature would also benefit from at least
one example expression, which should explicitly include the concrete
result you expect.  Here's one:

  (let-syntax
      ((foo (syntax-rules ()
	      ((foo x y ... z) (list x (list y ...) z)))))
    (foo 1 2 3 4 5))
  => (1 (2 3 4) 5)  

At the end of the SRFI:

  There is no 'official' reference implementation here provided,
  because this SRFI defines an extension to existing macro expanders,
  which all vary vastly in implementation.

I think you mean to say that it is impractical to provide a widely
ready-to-use implementation.

  Al* Petrofsky suggested that there still be here provided some
  examples of macro expanders that have been modified to support these
  extensions already;

Right, and that's what reference implementations are: implementations
to which people can refer when implementing the specification.

-al