Re: [racket-users] Behavior of nested ellipses

2018-03-28 Thread Justin Pombrio
> I don’t see why one is better than the other. 

I was surprised that the ellipsis which 'x' varies over changes between the 
pattern and the template. But it looks like no one else has the same 
intuition, so it's fine :-).

> Yes. See this part of the documentation of `syntax`: 

That's clear, thanks. I should have looked that up before asking.

On Wednesday, March 28, 2018 at 7:59:42 AM UTC-4, Matthew Flatt wrote:
>
> Just to answer some parts of the original question: 
>
> At Tue, 27 Mar 2018 13:01:54 -0700 (PDT), Justin Pombrio wrote: 
> > I'm surprised by the behavior of using a pattern variable under one set 
> of 
> > ellipses in the pattern, and under two sets of ellipses in the template: 
> > [...] 
> > Is this the expected behavior? 
>
> Yes. See this part of the documentation of `syntax`: 
>
>  If a pattern variable is replicated by more es in a template 
>  than the depth marker of its binding, then the pattern variable’s 
>  result is determined normally for inner es (up to the 
>  binding’s depth marker), and then the result is replicated as 
>  necessary to satisfy outer es. 
>
>
> > And is there a good reason for it? 
>
> If I remember correctly, I implemented a different behavior first, but 
> switched to be consistent with the `syntax-case` implementation. I also 
> vaguely remember that the switch made things work better. That was a 
> long time ago, though, so I may not remember correctly. 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Behavior of nested ellipses

2018-03-28 Thread Matthias Felleisen

> On Mar 27, 2018, at 11:58 PM, Justin Pombrio  wrote:
> 
> Matthias: the algorithm I was thinking of is the Macro-by-Example algorithm 
> that Ryan pointed out, which is neither of yours. Decompose the environment 
> at the outer ellipsis. I take back my claim that it's the most obvious 
> algorithm, though.


Well I sat with Eugene for most of the weekend in 87 when he implemented 
Mitch’s suggestions in extend-syntax. I surely misremembered the details, but 
it is easy to reconstruct that there are several alternatives of mapping at 
such points and that the algorithm has to proceed compositionally. The rest is 
a question of which of the alternatives you prefer. 

Eugene picked one that night, Racket picked a different one a few decades 
later. I don’t see why one is better than the other. 

— Matthias

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Behavior of nested ellipses

2018-03-27 Thread Justin Pombrio
I think I found a clearer way of talking about this. This rule:

(define-syntax-rule
(test (x y ...) ...)
'(((x y) ...) ...))

Has more than one possible meaning. But it can be clarified using explicit 
subscripts. It could mean either this (which is what I expected):

(define-syntax-rule
(test (x_j y_j_i ...i) ...j)
'(((x_j y_j_i) ...i) ...j))

Or this (which is what Racket does):

(define-syntax-rule
(test (x_j y_j_i ...i) ...j)
'(((x_i y_j_i) ...i) ...j))

I'm surprised that x's subscript changed between the pattern and the 
template.

Ryan, thanks for the interesting example. Made explicit, it becomes:

((x_j x_i ...i) ...j)

although figuring out how to label that was tricky and I don't know how to 
do it in general, or even if it can be done for all valid syntax rules.

Matthias: the algorithm I was thinking of is the Macro-by-Example algorithm 
that Ryan pointed out, which is neither of yours. Decompose the environment 
at the outer ellipsis. I take back my claim that it's the most obvious 
algorithm, though.

On Tuesday, March 27, 2018 at 6:05:12 PM UTC-4, Ryan Culpepper wrote:
>
> On 03/27/2018 11:46 PM, Ryan Culpepper wrote: 
> > On 03/27/2018 10:01 PM, Justin Pombrio wrote: 
> >> I'm surprised by the behavior of using a pattern variable under one 
> >> set of ellipses in the pattern, and under two sets of ellipses in the 
> >> template: 
> >> [...] 
>
> BTW, it looks like Macro-By-Example[1] describes the behavior that you 
> expected. See the definitions in the second column of page 4. 
>
> Ryan 
>
> [1] "Macro-By-Example: Deriving Syntactic Transformations from their 
> Specifications" by Eugene Kohlbecker and Mitchell Wand. 
> ftp://www.cs.indiana.edu/pub/techreports/TR206.pdf 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Behavior of nested ellipses

2018-03-27 Thread Ryan Culpepper

On 03/27/2018 11:46 PM, Ryan Culpepper wrote:

On 03/27/2018 10:01 PM, Justin Pombrio wrote:
I'm surprised by the behavior of using a pattern variable under one 
set of ellipses in the pattern, and under two sets of ellipses in the 
template:

[...]


BTW, it looks like Macro-By-Example[1] describes the behavior that you 
expected. See the definitions in the second column of page 4.


Ryan

[1] "Macro-By-Example: Deriving Syntactic Transformations from their 
Specifications" by Eugene Kohlbecker and Mitchell Wand. 
ftp://www.cs.indiana.edu/pub/techreports/TR206.pdf


--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Behavior of nested ellipses

2018-03-27 Thread Ryan Culpepper

On 03/27/2018 10:01 PM, Justin Pombrio wrote:
I'm surprised by the behavior of using a pattern variable under one set 
of ellipses in the pattern, and under two sets of ellipses in the template:


|
#lang racket

(require(for-syntax syntax/parse))

(define-syntax (test stx)
(syntax-parse stx
[(_ (x y ...)...)#''(top (list (x y) ...) ...)]))

(test (a 123)
(b 456)
(c 789))
|

I would expect this to produce:

|
'(top (list (a 1) (a 2) (a 3))
       (list (b 4) (b 5) (b 6))
       (list (c 7) (c 8) (c 9)))
|

But instead, it produces:

|
'(top (list (a 1) (b 2) (c 3))
       (list (a 4) (b 5) (c 6))
       (list (a 7) (b 8) (c 9)))
|

I'm surprised by this for two reasons:
- What I thought was the obvious implementation for 
matching/substituting with ellipses produces the top answer.

- It breaks some properties that I would expect ellipses to have, such as:

|
(define-syntax-rule (test (P ...))(list Q ...))
(test (T1 T2))
===
(define-syntax-rule (test P P*)(list Q Q*))
(test T1 T2)

;forall patterns P andtemplates Q andterms T1 andT2,whereP*andQ*are a 
renamed version of P andQ.

|


This has extra parens or is missing dots or something. As it is, the top 
test takes 1 argument and the bottom test takes two.



Is this the expected behavior? And is there a good reason for it?


A variable must participate in as many of the implicit maps in the 
template as its ellipsis depth from the *pattern* (call that depth D). 
If it occurs at a greater depth in the template, there are three obvious 
choices: participate in the outermost D maps, participate in the 
innermost D maps, or reject the template. At some point, someone decided 
to go with the innermost maps.


It's actually more complicated that that, because a variable can occur 
at multiple depths in the same template. Consider this example:


  > (with-syntax ([(x ...) #'(1 2 3)])
  #'((x x ...) ...))
  #

Instead of the property you were expecting, you get the following 
property: If T is a "fully-saturated" template (all variables occur wrt 
T at a depth >= their binding depths), then T always produces the same 
output, even when you put it in a larger template with more ellipses.


I think it might have been helpful back in the R5RS days, when 
"portable" macros were limited to syntax-rules, and this decision made a 
very limited system slightly more flexible. (To clarify, I'm not sure 
that R5RS specified this behavior, but I think it was a common extension 
to syntax-rules, whereas with-syntax was not.)


Nowadays, I would rather rewrite the macro to use with-syntax than rely 
on this "feature". I've implemented it twice, and I still have to stop 
and think through it.


Ryan

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.