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