1

C++ ブースト バインド ライブラリと clojure の部分関数は非常に似ています。例えば:

int x = 8;
bind(std::less<int>(), _1, 9)(x);   // x < 9

これは、clojure の部分関数に似ています。

((partial > 9) 8)

違いはpartial、最初の n 個のパラメーターのみをバインドできるのに対し、バインドされboost::bindているパラメーターとバインドされていないパラメーターを示すプレースホルダーを許可することです。したがってboost::bind、実際にははるかに一般的で便利です。

bind(f, _2, _1)(x, y);                 // f(y, x)

bind(g, _1, 9, _1)(x);                 // g(x, 9, x) 

boost::bindclojure(またはclojure-contrib)に似たものがあるかどうか疑問に思っていますか?そして、なぜパーシャルはより一般的 (かつ有用) に書かれていなかったのboost::bindでしょうか?

4

3 に答える 3

7

これは、Clojure に関してかなり頻繁に尋ねられる質問であり、スレッド化マクロ -> および ->> に関して、それらが任意のプレースホルダーを許可しない理由について言及されることがよくあります。

私の意見では、これらの理由はここでも当てはまります。慣用的な Clojure 関数は、一般に、混合ではなく、最初または最後の引数を別々に提供するのに適したものに分類されます。

言い換えれば、開発者は通常、->、->>、および/または部分的に対応できるように関数をコーディングしようとします。

無名関数のリーダー マクロを考えると、必要に応じてプレースホルダー バージョンを作成するのはかなり簡単です。

#(f %2 %1) ;; bind(f, _2, _1)
#(g % 9 %) ;; bind(g, _1, 9, _1)
于 2012-06-30T18:48:01.153 に答える
0

他のさまざまなパラメータのスレッド化/バインディングシナリオを可能にするSwissArrowsライブラリがあります。ただし、そこには非常に多くのオプションがあるため、関数のパラメーターを最適化して->および->>マクロを最適に使用することをお勧めします。それが不可能な場合は、無名関数を最も単純な一般的な解決策として使用してください。

于 2012-07-02T09:27:55.017 に答える
0

ショーンが言ったようにpartial、より具体的な問題を解決し、一般に、ラムダは慣用的な解決策です。とはいえ、もしあなたが必死なら、い​​つでも自分でロールすることができますbind:

(defmacro bind
  [bound-function & args]
  (let [; helper function to parse actual argument symbols
        get-symbols (fn [s] (map second s)),
        ; help function to get the placeholder arguments
        get-placeholders (fn [s] (filter first s))
        ; collection of arguments and whether they're placeholders
        bound-args (map (fn [arg]
                        (if (= arg '_)
                          ; for placeholders, generate a new symbol
                          [true (gensym)]
                          ; otherwise, use the provided argument as-is
                          [false arg]))
                      args)]
    `(fn [~@(get-symbols (get-placeholders bound-args))]
       (~bound-function ~@(get-symbols bound-args)))))

その使用法は次のとおりです。

((bind > 9 _) 8) ; true
((bind > _ _) 9 8 ) ; true
于 2012-06-30T19:45:28.393 に答える