2011-06-20 11 views
1

previous questionへのフォローアップとして、私はdefprotocolを構築するマクロを記述しようとしています:ビルドプロトコルClojureのマクロ

(build-protocol AProtocol 
    [(a-method [this]) (b-method [this that])] 
    (map (fn [name] `(~(symbol (str name "-method")) [~'this ~'that ~'the-other])) 
    ["foo" "bar" "baz"]) 
    (map (fn [name] `(~(symbol (str name "-method")) [~'_])) 
    ["hello" "goodbye"])) 

(defprotocol AProtocol 
    (a-method [this]) 
    (b-method [this that]) 
    (foo-method [this that the-other]) 
    (bar-method [this that the-other]) 
    (baz-method [this that the-other]) 
    (hello-fn [_]) 
    (goodbye-fn [_])) 

私の試みに展開する必要があります

(defmacro build-protocol [name simple & complex] 
    `(defprotocol ~name [email protected] 
    [email protected](loop [complex complex ret []] 
     (if (seq complex) 
      (recur (rest complex) (into ret (eval (first complex)))) 
      ret)))) 

および拡張(macroexpand-1 '(...))

(clojure.core/defprotocol AProtocol 
    (a-method [this]) 
    (b-method [this that]) 
    (foo-method [this that the-other]) 
    (bar-method [this that the-other]) 
    (baz-method [this that the-other]) 
    (hello-method [_]) 
    (goodbye-method [_])) 

私はevalについて本当に満足していません。また、mapという表現はかなり醜いです。より良い方法がありますか?すべてのコメントは大歓迎です。

私がこの作業をしたら、(build-reify ...)のために同様のマクロを実行します。私はかなり大きなSwingアプリケーションを作成しており、いくつかのコンポーネント(JButtons、JCheckBoxなど)はほとんど同じメソッドシグネチャとアクションを持っています。

答えて

2

あなたはそれを逆さまにしていると思います。ある種のコンテナに包まれた "-method"のものをまず指定して、何が何かを知っていて、マクロ内でマップを実行させるようにします。例:

(build-protocol AProtocol 
    {[this that whatever] [foo bar baz], 
    [_] [hello goodbye]} 
    ; a-method and b-method... 
) 
+0

興味深い考えです。私はそれを探求する必要があります。 – Ralph

+0

を参照してくださいには、例えば、https://github.com/amalloy/ordered/blob/develop/src/deftype/delegate.clj - 私は週末にこれを書いたし、今朝でそれを確認しました。それは私があなたがお勧めほとんど同じように、(https://github.com/amalloy/ordered/blob/develop/src/ordered/map.cljで使用で見られる)新しい '委任-deftype'を定義し'ビルド-protocol'。 – amalloy

+0

私は先に行って、あなたは私が何を意味するか見ることができるようにあなたのためにこれの草稿を実装@Ralph:https://github.com/amalloy/build-protocol/blob/develop/src/build_protocol/core.clj – amalloy

関連する問題