Ambiguity of extra ellipses in syntax-rules templates Al-Pastor Petrofsky (09 Mar 2017 06:40 UTC)
Re: Ambiguity of extra ellipses in syntax-rules templates Marc Nieper-Wißkirchen (13 Mar 2017 21:04 UTC)

Ambiguity of extra ellipses in syntax-rules templates Al-Pastor Petrofsky 09 Mar 2017 06:39 UTC

In the current SRFI-149 draft, the Rationale section says:

   The second unnatural restriction of the pattern language as
   described in the R7RS is that a difference is made between pattern
   variables that occur in subpatterns followed by no instance of the
   identifier <ellipsis> and those that occur in subpatterns followed
   by one or more instances of the identifier <ellipsis>, while there
   is no logical reason why such a difference has to be made.

There is a logical reason for the restriction.  Allowing pattern
variables with non-zero ellipsis count to have extra ellipses in the
template has an ambiguous meaning, in contrast to allowing this for
zero-ellipsis variables, which is unambiguous.

Suppose you have a macro that takes a list of axis names and a set of
coordinates, and it expands to a list with each coordinate labeled
with its axis:

(define-syntax foo
  (syntax-rules ()
    ((foo (axis ...) (coordinate ...))
     '((axis coordinate) ...))))
(foo (x y) (0 0))
=> ((x 0) (y 0))

And suppose you extend that macro to allow multiple sets of
coordinates to be labeled:

(define-syntax foo2
  (syntax-rules ()
    ((foo2 (axis ...) (coordinate ...) ...)
     '(((axis coordinate) ...) ...))))

(foo2 (x y) (0 0) (0 3))
=> (((x 0) (y 0))
    ((x 0) (y 3)))

(foo2 (x y) (0 0) (0 3) (3 4))
=> (((x 0) (y 0))
    ((x 0) (y 3))
    ((x 3) (y 4)))

I haven't tried to understand the sample implementation, but I'm
guessing it would unexpectedly expand these examples like this:

(foo2 (x y) (0 0) (0 3))
=> (((x 0) (x 0))
    ((y 0) (y 3)))

(foo2 (x y) (0 0) (0 3) (3 4))
=> syntax error (mismatching sequence lengths)

The ambiguity is in which of the ellipses in the template should
iterate and which should replicate.  In other words, which ones should
be considered the ellipses that correspond to the ellipses in the
pattern, and which ones should be considered the extra ellipses.

In r7rs there's no ambiguity: for any variable, either all of the
ellipses in the template iterate (because the number of ellipses in
the pattern and template match), or they all replicate (because there
were no ellipses for this variable in the pattern).

The Specification section says:

   If a pattern variable in a subtemplate is followed by more
   instances of <ellipsis> than the subpattern in which it occurs is
   followed, the input elements by which it is replaced in the output
   are repeated for every excess instance of <ellipsis> on the left.

I guess the phrase "on the left" is intended to be the arbitrary
resolution to this ambiguity, but it's hardly clear, because: (1) all
ellipses occur on the right of a variable, none "on the left"; and (2)
up until this point the draft hasn't acknowledged the existence of any
ambiguity nor what the two choices are for resolving it.

I suggest the Rationale section add some discussion of this issue, and
the wording in the Specification be changed to use "innermost" rather
than "on the left", e.g., "are repeated for the innermost excess
instances of <ellipsis>".

-al