問題タブ [multimethod]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
loops - マクロの引数をループする
一連の単純な「def」式の評価を可能にするマクロを Clojure で作成しようとしています。マクロに関しては、私は初心者です。アイデアは、
に展開する必要があります
次のコードは、2 つの定義の特殊なケースでこれを実現します。
これはいいことですが、これを一般化するのに苦労しています。の要素のバインディングをループすることを含む単純なことをいくつか試してみましたが、(partition 2 args)
常にガベージが発生しました (これはあまり具体的ではないことはわかっていますが、ガベージの多様性と範囲はここで報告するには多すぎるように思えました)。これらをループして定義を評価するにはどうすればよいですか?
PSマクロmy-defs
はおもちゃです。最終的に私が本当に達成したいのは、マルチメソッド インスタンスの束をインスタンス化する小さなヘルパー マクロです。現在、私は次のようなコードの大きな塊を持っています
これは少し見苦しいです。のようなことができればいいのですが
代わりは。
clojure - スキーム->Clojure:メソッドに述語を含むマルチメソッド?
いくつかのSchemeコードをClojureに変換しています。オリジナルは、マルチメソッドに非常に似ているディスパッチングパターンを使用していますが、一致する述語へのアプローチが逆になっています。たとえば、総称関数「assign-operations」があります。現時点では、正確な実装の詳細はそれほど重要ではありませんが、引数述語のリストを取得できることに注意してください。
ディスパッチされた関数は、関数のアリティの引数ごとに1つずつ、これらの述語を提供します。
後で、ジェネリック関数 "merge"が呼び出されると、各ハンドラーは、オペランドで機能するかどうかを尋ねられます。
マルチメソッドを理解しているので、ディスパッチ関数は実装のセット全体で定義され、dispatch-fnの戻り値に基づいて特定のメソッドにディスパッチされます。上記のスキームでは、新しい割り当て操作関数で述語を任意に定義できます。
Clojureの同等の慣用的な構成は何でしょうか?
編集:上記のコードは、AlexeyRadulとGeraldSussmanによる「TheArtofthePropagator 」からのものです。
clojure - Clojureマルチメソッドとプロトコル
私はClojureの初心者で、プロトコルを使用する場合とマルチメソッドを使用する場合の具体的な例を探していました。プロトコルは一般に型階層と典型的なOOPのものを作成することを目的としていること、それらはマルチメソッドの後に言語に追加されたこと、そしてプロトコルは一般的にパフォーマンスが優れていることを知っているので、私の質問はこれです:
プロトコルはマルチメソッドを置き換えることを目的としていますか?そうでない場合は、プロトコルの代わりにマルチメソッドを使用する例を教えてください。
emacs - Slimeを介したマルチメソッドのリロード
Slime replを使用してEmacsで開発するときに、マルチメソッドをリロードするのに問題があります。
フォームの再定義はdefmethod
正常に機能しますが、ディスパッチ機能を変更すると、フォームをリロードできないようですdefmulti
。ディスパッチ関数のパラメーターを具体的に追加または削除したと思います。
ns-unmap
回避策として、マルチメソッド変数を実行し、フォームをリロードdefmulti
してから、すべてのフォームをリロードすることができましたdefmethod
。
おそらく、これはClojureがマルチメソッドを実装する方法の「制限」です。つまり、実行速度のためにいくつかのダイナミズムを犠牲にしていますが、これを回避するのに役立つイディオムや開発手法はありますか?
c# - C#での静的(コンパイル時/厳密に型指定された)マルチディスパッチのサポート
最近、コードで同じパターンを何度も使用していることに気付きました。基本的に、基本クラスのインスタンスへの参照を派生したものに解決するために使用するのは、ビジターパターンのバリエーションです。このアプローチには、多くの定型コードが必要です。
質問:
- 大量の訪問者コードを記述せずに、静的/厳密に型指定された方法でC#のメソッドをマルチディスパッチするにはどうすればよいですか?
- このコードを生成するツール/拡張機能はありますか?
- マルチディスパッチに対応するC#言語がないのはなぜですか?これが面倒だと思うのは私だけではないと思います。私はひどく間違っているかもしれませんし、問題は存在しませんので、あなたがそれをどのように進めているのか知りたいです。
clojure - マルチメソッドは名前空間の問題をどのように解決しますか?
私はプログラミング言語の設計を研究しており、一般的な単一ディスパッチ メッセージ パッシング OO パラダイムをマルチメソッド ジェネリック関数パラダイムに置き換える方法の問題に興味があります。ほとんどの場合、それは非常に簡単に思えますが、最近行き詰まってしまったので、助けていただければ幸いです。
私の考えでは、メッセージ パッシング OO は、2 つの異なる問題を解決する 1 つのソリューションです。次の疑似コードで、私が何を意味するかを詳しく説明します。
(1) ディスパッチの問題を解決します。
=== ファイル animal.code ===
=== ファイル内 myprogram.code ===
この問題では、「樹皮」は、引数の型に応じて異なる動作をする複数の「分岐」を持つ 1 つのメソッドです。対象の引数の型 (Dogs と Cats) ごとに「bark」を 1 回実装します。実行時に、動物のリストを繰り返し処理し、適切な分岐を動的に選択できます。
(2) 名前空間の問題を解決します。
=== ファイル animal.code ===
=== ファイル tree.code ===
=== ファイル内 myprogram.code ===
この問題では、「樹皮」は、実際には、たまたま同じ名前を持つ 2 つの概念的に異なる機能です。引数の型 (dog か tree か) によって、実際にどちらの関数を意味するかが決まります。
マルチメソッドは問題番号 1 をエレガントに解決します。しかし、問題番号 2 をどのように解決するかはわかりません。たとえば、上記の 2 つの例の最初の例は、単純な方法でマルチメソッドに変換できます。
(1) マルチメソッドを使用する犬と猫
=== ファイル animal.code ===
=== ファイル内 myprogram.code ===
キーポイントは、メソッド bark(Dog) が概念的に bark(Cat) に関連していることです。2 番目の例にはこの属性がありません。そのため、マルチメソッドが名前空間の問題を解決する方法がわかりません。
(2) マルチメソッドが動物と木で機能しない理由
=== ファイル animal.code ===
=== ファイル tree.code ===
=== ファイル内 myprogram.code ===
この場合、ジェネリック関数はどこに定義する必要がありますか? animal と tree の両方の上にあるトップレベルで定義する必要がありますか? 2 つの関数は概念的に異なるため、動物と木の樹皮を同じジェネリック関数の 2 つのメソッドと考えるのは意味がありません。
私の知る限り、この問題を解決した過去の作品はまだ見つかっていません。Clojure マルチメソッドと CLOS マルチメソッドを見てきましたが、同じ問題があります。私は指を交差させて、問題に対するエレガントな解決策、または実際のプログラミングで実際に問題にならない理由についての説得力のある議論のいずれかを望んでいます。
質問に明確化が必要な場合はお知らせください。これはかなり微妙な(しかし重要な)ポイントだと思います。
返事の正気、Rainer、Marcin、および Matthias に感謝します。私はあなたの返信を理解し、動的ディスパッチと名前空間の解決が 2 つの異なるものであることに完全に同意します。CLOS は 2 つのアイデアを混同しませんが、従来のメッセージ パッシング OO は混同します。これにより、マルチメソッドを多重継承に簡単に拡張することもできます。
私の質問は、具体的には、融合が望ましい状況にあります。
以下は、私が言いたいことの例です。
=== ファイル: XYZ.code ===
=== ファイル: POINT.code ===
=== ファイル: GENE.code ===
==== ファイル: my_program.code ===
名前空間の解決とディスパッチが混同されているため、プログラマーは 3 つのオブジェクトすべてに対して単純に get-x() を呼び出すことができます。これも完全に明白です。各オブジェクトは独自のメソッド セットを「所有」しているため、プログラマーが何を意図したかについて混乱することはありません。
これをマルチメソッド バージョンと比較してください。
=== ファイル: XYZ.code ===
=== ファイル: POINT.code ===
=== ファイル: GENE.code ===
==== ファイル: my_program.code ===
XYZ の get-x() は GENE の get-x() と概念的な関係がないため、これらは別のジェネリック関数として実装されています。したがって、エンド プログラマー (my_program.code 内) は get-x() を明示的に修飾し、実際にどのget-x() を呼び出すつもりかをシステムに伝える必要があります。
確かに、この明示的なアプローチはより明確であり、複数のディスパッチと複数の継承に簡単に一般化できます。しかし、名前空間の問題を解決するためにディスパッチを (悪用して) 使用することは、メッセージ パッシング OO の非常に便利な機能です。
個人的には、自分のコードの 98% が単一ディスパッチと単一継承を使用して適切に表現されていると感じています。私は複数のディスパッチを使用するよりも、名前空間の解決にディスパッチを使用するこの便利さを使用しているため、それをあきらめたくありません。
両方の長所を活かす方法はありますか? マルチメソッド設定で関数呼び出しを明示的に修飾する必要をなくすにはどうすればよいですか?
という意見が一致しているようです
- マルチメソッドはディスパッチの問題を解決しますが、名前空間の問題には取り組みません。
- 概念的に異なる関数には異なる名前を付ける必要があり、ユーザーはそれらを手動で修飾する必要があります。
したがって、単一継承の単一ディスパッチで十分な場合は、ジェネリック関数よりもメッセージ パッシング OO の方が便利だと思います。
これはオープンリサーチのようですね。名前空間の解決にも使用できるマルチメソッドのメカニズムを言語が提供する場合、それは望ましい機能でしょうか?
私はジェネリック関数の概念が好きですが、現在のところ、「些細なことを少し煩わしく」することを犠牲にして、「非常に難しいことをそれほど難しくない」ように最適化されていると感じています. コードの大部分は些細なものなので、これは解決する価値のある問題であると私は信じています。
clojure - Clojureのマルチメソッドが「if」または「case」ステートメントよりも優れているのはなぜですか
Clojureのマルチメソッドを理解しようと、しばらく時間を費やしました。私が理解している限り、主な「プロ」マルチメソッドの議論はその柔軟性ですが、マルチメソッドが単純なifまたはcaseステートメントよりも優れている理由の議論と混同しています。誰か、ポリモーフィズムと誇張されたcaseステートメントの境界線はどこにあるのか説明してもらえますか?
編集:「if」ステートメントと比較してもっと興味があるという質問をもっと明確にすべきでした。答えてくれてありがとう!
perl - Class :: Multimethods :: Pureを拡張する方法Mooseの役割を認識しますか?
Mooseオブジェクトを使用したmultemethodディスパッチが必要です。私はこれをClass::Multimethods::Pureで行っています。MooseX :: Method :: Signaturesに依存しているため、 MooseX :: MultiMethodsの代わりにこれを選択しました。これは、テストに失敗したためにシステムにインストールできません。提案する別のアプローチがあるかどうかは気にしません。
以下は、タイプとサブタイプで正常に機能します。
しかし、私が今処理する必要があるシナリオは、宣言されたタイプが実際にはMooseロールである場合です。
しかし、これは役割を認識できません。
ドキュメントには、Perl 6風の役割の追加など、さまざまな方法で拡張できると記載されています。しかし、それは私には少し大雑把であり、私はより詳細な例を探しています。誰かがこれを試しましたか?
clojure - マルチメソッドの一般的な構文
質問が些細な場合は申し訳ありませんが、グーグルで調べてもどこにも導かれません。defmulti
との一般的な構文は何defmethod
ですか? 単純なマルチメソッドを書くことはできますが、docstring、前後の条件、メタデータなどをどこに置けばよいかわかりません。
実はClojureよりもClojureScriptに興味があるので、両者の違いがあれば教えてください。