2016-01-13 47 views
3

这个问题很难解释,因为我需要收集我的想法,所以请耐心等待。为了说明的目的,我已经能够将问题简化为一个最小的例子。这个例子对于这对于什么是有用的没有任何意义,但我离题了。说我想延长球拍语言写的东西看起来像这样:球拍宏定义给定重复模式的功能

(define-something 
    (['a] 'whatever) 
    (['b 'c] 'whatever2)) 

方括号中的是一个或多个符号的序列,其次是球拍的表达式(在whatever的,一个序列是不是问题陈述重要)

的例子将匹配一个宏,看起来是这样的:

(define-syntax (define-something stx) 
    (syntax-case stx() 
    [(_ ([symb ...] body ...) ...) 
    #'()])) 

其实我们在这里0或多个符号匹配,但我们可以假设有总是将是最后一个。

在宏的正文中,我想用连接符号作为标识符来生成函数定义。所以对于我们的傻例如宏将扩展为类似:

(define (a) 'whatever) 
(define (bc) 'whatever2) 

我已经找到了similar question在海报生成使用字符串的预定义列表的功能,但我不流利与宏观的,所以我有没有能够翻译的概念来解决我的问题。我想也许我可以尝试生成一个类似的列表(通过连接这些符号)并应用它们的策略,但是我一直对我的宏定义中的所有省略号感到困惑。我也对他们在with-syntax中使用省略号感到困惑。

+0

这只是一个练习来帮助学习宏,或者是否有任何目的?它在规定的表格中似乎不是非常有用。 –

+0

我实际上想要做的是在反应式编程的背景下。这些符号实际上是无功信号(我可能会减少为每个信号的唯一符号)。当一个信号改变时(例如信号'a'),我执行'任何'的身体。当两个信号'a'和'c'改变(并且一个主体被定义为'a'和'c')时,我想执行'whatever2。一旦这些方法已经作为球拍类的一部分生成,使用动态发送(它接受符号方法名称)实际上很容易调用它们。对不起,这需要更多的解释,但我仍在试验自己。 – Sam

+0

为什么我想要生成方法的另一个(主要)原因是我可以非常方便地向这些​​方法添加参数。然后这些参数可以在方法的生成主体中使用,就好像它们只是“存在”一样,我不用担心以另一种方式引入这些“魔术变量”。如果你想要更多的信息,或者包含比tweet更多的字符的合理解释,我会很乐意提供它! – Sam

回答

4

可以用with-syntaxsyntax-case解决这个问题,但最简单的方法是使用syntax-parse的语法类。通过定义解析符号列表,并产生一个单一串联标识符的语法类,可以解除符号解析出的宏体:

(require (for-syntax syntax/parse 
        racket/string)) 

(begin-for-syntax 
    (define-syntax-class sym-list 
    #:attributes [concatenated-id] 
    (pattern (~and stx (sym:id ...)) 
      #:attr concatenated-id 
      (let* ([syms (syntax->datum #'(sym ...))] 
        [strs (map symbol->string syms)] 
        [str (string-append* strs)] 
        [sym (string->symbol str)]) 
       (datum->syntax #'stx sym #'stx #'stx))))) 

现在,您可以定义您的宏很容易:

(define-syntax (define-something stx) 
    (syntax-parse stx 
    [(_ (syms:sym-list body ...) ...) 
    #'(begin 
     (define (syms.concatenated-id) body ...) 
     ...)])) 

注意,这里使用不带引号的符号名子句中,所以它的工作是这样的:

(define-something 
    ([a] 'whatever) 
    ([b c] 'whatever2)) 

名称不能计算结果为符号表达,因为需要在编译时了解信息以供宏观扩展。既然你在评论中提到这是一个类似FRP的系统,你的信号图必须是静态的,比如Elm's。如果您想要构建动态信号图的能力,您需要比宏更复杂的策略,因为这些信息需要在运行时解决。

+0

是的,信号图是静态的:)我将尝试一下语法分析。谢谢! – Sam