Ah, okay, so... this macro expander you give is fundamentally flawed because 
match-define does an initial parse (which uses the match expander) to get the 
identifiers it is going to define. So, when you expand to x3 as the match 
pattern, you end up returning x3 as one of the values that the match-define -> 
define-values is going to define. It does not ever define "x" as anything 
because that was just arbitrary syntax that was given to the match expander. 
This x3 is x3 definition leads to a use-before-initialization error.

Do you have a different example that doesn't fail in this way?
-Ian
----- Original Message -----
From: "J. Ian Johnson" <[email protected]>
To: "J. Ian Johnson" <[email protected]>
Cc: "racket users list" <[email protected]>, "Alexander D. Knauth" 
<[email protected]>
Sent: Friday, August 1, 2014 7:47:04 PM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] getting one macro to tell another macro to define 
something

Okay, define-forms.rkt had some uses of parse outside of gen-match's "go" which 
sets the parameter, so I fixed that. Now it turns out the docs are imprecise 
for make-syntax-delta-introducer's first argument. It wants an identifier 
rather than an arbitrary piece of syntax. Not sure why that's necessary. I'm 
going to stop and wait for ryanc or mflatt to respond to this thread. I'm out 
of ideas.
-Ian
----- Original Message -----
From: "J. Ian Johnson" <[email protected]>
To: "Alexander D. Knauth" <[email protected]>
Cc: "racket users list" <[email protected]>, "J. Ian Johnson" 
<[email protected]>
Sent: Friday, August 1, 2014 7:30:10 PM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] getting one macro to tell another macro to define 
something

Well, I just hacked racket/match to allow match-expanders to take a third 
argument that is the introducer for the application. No permutation of mark 
applications works, I think since syntax-local-introduce does not include all 
the marks from the top use of match-define all the way through internal macros 
to the transformer call. I'm currently looking into getting a delta-introducer 
sent to the transformer that has the delta between the original match syntax 
and the match-expander syntax, but I'm fighting the implementation in actually 
getting the orig-stx parameter set to the right thing. 
-Ian
----- Original Message -----
From: "Alexander D. Knauth" <[email protected]>
To: "J. Ian Johnson" <[email protected]>
Cc: "racket users list" <[email protected]>
Sent: Friday, August 1, 2014 7:17:53 PM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] getting one macro to tell another macro to define 
something


I found this on line 2327 of racket/src/racket/src/env.c: 

static Scheme_Object * 
local_introduce ( int argc , Scheme_Object * argv []) 
{ 
Scheme_Comp_Env * env ; 
Scheme_Object * s ; 


env = scheme_current_thread -> current_local_env ; 
if ( ! env ) 
not_currently_transforming ( "syntax-local-introduce" ); 


s = argv [ 0 ]; 
if ( ! SCHEME_STXP ( s )) 
scheme_wrong_contract ( "syntax-local-introduce" , "syntax?" , 0 , argc , argv 
); 


if ( scheme_current_thread -> current_local_mark ) 
s = scheme_add_remove_mark ( s , scheme_current_thread -> current_local_mark ); 


return s ; 
} 
What would happen if match-expander-transform somehow set scheme_current_thread 
-> current_local_mark to the mark produced by the new syntax-introducer? And 
would that even be possible? (without fundamental changes to racket) 



On Aug 1, 2014, at 6:45 PM, J. Ian Johnson < [email protected] > wrote: 


Well one problem is expander application his its own mark to deal with, so you 
can't cancel the mark on x. 

https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157
 

Another problem is expecting the implementation of match-define to not have any 
inner macros that would change syntax-local-introduce to a less helpful extent. 
What would be ideal is if racket/match could change some "parameter" so that 
syntax-local-introduce used the introducer defined in the above link, since the 
generated temporary does not have x's mark that x has annihilated. Instead x's 
mark will be added to tmp after the transformer returns, and there's nothing 
you can do about it :( 

-Ian 
----- Original Message ----- 
From: "Alexander D. Knauth" <[email protected]> 
To: "J. Ian Johnson" <[email protected]> 
Cc: "racket users list" <[email protected]> 
Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern 
Subject: Re: [racket] getting one macro to tell another macro to define 
something 

Well, if the match-expander is invoked in the “dynamic extent” of the 
match-define form, then would syntax-local-introduce apply that syntax-mark? 

On Aug 1, 2014, at 6:20 PM, J. Ian Johnson <[email protected]> wrote: 



Well that's a pickle. I can tell you that (mac . args) gets expanded as 
(X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is 
applied to something with m already, they annihilate each other (see Syntactic 
Abstraction in Scheme for how this totally works). 
The syntax-local-introduce form allows you to apply the macro application's 
mark to an arbitrary piece of syntax, so later on the application's mark will 
annihilate it and voila`, it's like it was textually given to the macro 
application itself. 

Here, however, a match expander is not treated as a macro invocation. There is 
no mark for that match-expander use to introduce. There is, however, the mark 
from match-define that you'll want to introduce to this temporary you've 
generated. I think. I haven't quite worked out how to make this work. 
-Ian 
----- Original Message ----- 
From: "Alexander D. Knauth" <[email protected]> 
To: "racket users list" <[email protected]> 
Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern 
Subject: Re: [racket] getting one macro to tell another macro to define 
something 





On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < [email protected] > wrote: 


It's best to expand into a begin-for-syntax that does the desired mutation, 
rather than mutate within the transformer. You currently _cannot_ do this 
outside top level forms. 



The reason I can’t do that is because in the real program, sender is actually a 
match-expander. 


You are also right about the marks. The call to receiver adds additional marks 
to the definitions that it pulls out, so you'll need to apply 
syntax-local-introduce. ... 




On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < [email protected] > wrote: 


Use syntax-local-introduce when putting syntax into a side-channel or getting 
it back out across macro calls. This only matters when the syntax represents a 
definition or more generally contains binders whose references are not all in 
the same syntax. 
... 


Thanks, the syntax-local-introduce got it working for that example, but for 
some reason it’s not working when sender is a match-expander. 

I’m still not very clear on when to use syntax-local-introduce and when not to, 
or even what it does (other than get that example working), so could someone 
point me in the right direction? 



#lang racket 
(require racket/stxparam 
(for-syntax syntax/parse 
racket/syntax 
racket/set)) 
;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) 
(define-syntax-parameter current-defs #f) 
(define-match-expander sender 
(lambda (stx) 
(syntax-parse stx 
[(sender x) 
#:with tmp (generate-temporary #'x) 
(define defs (syntax-parameter-value #'current-defs)) 
(set-add! defs (syntax-local-introduce #'(define x tmp))) 
#'tmp]))) 
(define-syntax reciever 
(lambda (stx) 
(syntax-parse stx 
[(reciever) 
(define defs (syntax-parameter-value #'current-defs)) 
(with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) 
#'(begin def ...))]))) 


(syntax-parameterize ([current-defs (mutable-set)]) 
(match-define (sender x) 1) 
(reciever) 
x) 


;x3: unbound identifier; 
; also, no #%top syntax transformer is bound in: x3 




____________________ 
Racket Users list: 
http://lists.racket-lang.org/users 



____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to