2016-01-13 82 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