多重ディスパッチ: Multiple dispatch)は、多重定義された関数メソッドマルチメソッド: Multimethods)などと呼ばれる)などについて、そこで呼び出されるべき1つの定義を動的に選んで実行する(動的ディスパッチする)際に、2個以上の複数の引数が関与してどれかひとつを選ぶこと(特殊化)がおこなわれるものである。

概要

編集

多重定義を許すプログラミング言語では、同一の名前の(すなわち、多重定義された)関数メソッドのうちのどれを呼出す(ディスパッチする)かを決定する、ということをしなければならない。

多くのオブジェクト指向プログラミング言語は単一ディスパッチである。すなわち、メソッド呼び出し(Smalltalkなら「メッセージ送信」、C++なら「メンバ関数呼び出し」)において、引数の1つが特別に扱われ、呼び出すべきメソッドの特定に使われる。構文上もその引数を特別に扱い、ドットを挟んで、そのオブジェクトを選択する式と、呼び出すべきメソッドの名前を記述する(例えばspecial.meth(other,args,here))。(これは、そのような言語ではそのメソッドをそのオブジェクトが「所有する」ような形となるため、オブジェクトによって名前空間を指定するのが自然であるため、という理由もある)

多重ディスパッチを採用する言語では、全ての引数をメソッド選択に参加させることが可能である。第一引数、第二引数、第三引数とマッチングを行うが、どれか特定の引数がその関数やメソッドを「所有」しているわけではない。二項演算子(関数)のような、2引数の場合のみを対象とする多重ディスパッチをダブルディスパッチといい、関数やメソッドの多重ディスパッチは無い言語でも、二項演算子にはダブルディスパッチがある、といった言語もある。

言語機能として多重ディスパッチを採用した初期の例としては Common Lisp がある。

編集

多重ディスパッチと単一ディスパッチの違いは例を見れば明らかになるだろう。宇宙船や小惑星といったオブジェクトが出てくるゲームを想定する。2つのオブジェクトが衝突する場合、何と何が衝突するかによってプログラムは様々な反応をすると想定する。

Common Lisp

編集

Common Lispのように多重ディスパッチをする言語では、コードは次のようになる。

 (defmethod collide-with ((x asteroid) (y asteroid))
   ;; 小惑星が小惑星に衝突する場合を処理
   ...)
 (defmethod collide-with ((x asteroid) (y spaceship))
   ;; 小惑星が宇宙船に衝突する場合を処理
   ...)
 (defmethod collide-with ((x spaceship) (y asteroid))
   ;; 宇宙船が小惑星に衝突する場合を処理
   ...)
 (defmethod collide-with ((x spaceship) (y spaceship))
   ;; 宇宙船が宇宙船に衝突する場合を処理
   ...)

このように、引数のデータ型を調べるコードを、引数部分に完全に組み込むことができている。

多重ディスパッチがあると、クラスがあって、そこにメソッドが属しているという考え方はあまり意味を持たない。collide-with という名前のメソッドは、引数ごとにそれぞれ2つのクラスと関連付けられている「普通の関数呼び出し」に過ぎなくなる。結果として、メソッドを呼び出す際の特殊な構文を必要としない。

Python

編集

言語として多重ディスパッチをサポートしていない場合でも、ライブラリによる拡張で多重ディスパッチ機能を追加することは可能である。 一例を挙げるとmultimethods.pyモジュールがあり、次のように記述可能である。

from multimethods import Dispatch
from game_objects import Asteroid, Spaceship
from game_behaviors import ASFunc, SSFunc, SAFunc
collide = Dispatch()
collide.add_rule((Asteroid, Spaceship), ASFunc)
collide.add_rule((Spaceship, Spaceship), SSFunc)
collide.add_rule((Spaceship, Asteroid), SAFunc)
def AAFunc(a, b):
    "Behavior when asteroid hits asteroid"
    # ...define new behavior...
collide.add_rule((Asteroid, Asteroid), AAFunc)

# ...later...
collide(thing1, thing2)

Python 2.4 の decorators を使って、グイド・ヴァンロッサムはマルチメソッドのサンプル実装を行い[1]、構文を単純化した。

@multimethod(Asteroid, Asteroid)
def collide(a, b):
    "Behavior when asteroid hits asteroid"
    # ...define new behavior...
@multimethod(Asteroid, Spaceship)
def collide(a, b):
    "Behavior when asteroid hits spaceship"
    # ...define new behavior...
# ... define other multimethod rules ...

Java

編集

Java のように単一ディスパッチしかしない言語では、コードは次のようになる(ただし、Visitor パターンをこれに活用することも可能)。

/* Java の "instanceof" オペレータを使って、実行時のデータ型比較をする */
class Asteroid extends Thing {
    public void collide_with(Thing other) {
        if (other instanceof Asteroid) {
            // 小惑星と小惑星の衝突を処理
        }
        else if (other instanceof Spaceship) {
            // 小惑星と宇宙船の衝突を処理
        }
    }
}
 
class Spaceship extends Thing {
    public void collide_with(Thing other) {
        if (other instanceof Asteroid) {
            // 宇宙船と小惑星の衝突を処理
        }
        else if (other instanceof Spaceship) {
            // 宇宙船と宇宙船の衝突を処理
        }
    }
}


プログラミング言語におけるサポート

編集

以下は、何らかの拡張なしに、多重ディスパッチ機構を持つ言語の例である。

以下は、多重ディスパッチのような機構のための何らかの拡張の例(及びその言語)である。

参考文献

編集

📚 Artikel Terkait di Wikipedia

ビリー・ミリガン

later, multiple-personality case still fascinates", The Columbus Dispatch, 28 October 2007 ^ Billy Milligan dies at 59; first to use multiple personality

R8000

Technologies, Inc. 1994 ^ Unekawa 1993 "Aligning Instructions for Multiple Dispatch". Sidebar in Pountain, Dick, "The Last Bastion", Byte, August 1994

サンディフック小学校銃乱射事件

2012年12月15日閲覧。  ^ “Newtown school shooting: Transcript of police, fire radio dispatch”. New Haven Register (New Haven, Connecticut). (2012年12月14日). http://nhregister

24人のビリー・ミリガン

[脚注の使い方] ^ “30 years later, multiple-personality case still fascinating”. The Columbus Dispatch. 2012年7月31日時点のオリジナルよりアーカイブ。2015年10月15日閲覧。

R・ケリー

Our music critic is finished with the Pied Piper of R&B”. St. Louis Post-Dispatch (2018年8月12日). 2021年9月28日時点のオリジナルよりアーカイブ。2019年1月9日閲覧。 ^ Williams, Stereo

Facebookへの批判

化し、大学のパスワードをアクセスに使用しないよう注意メッセージを表示した。UNMは次の春学期にアクセスブロックを解除した。 Columbus Dispatch の2006年6月22日の報道によると、ケント州立大学の運動部顧問 が選手によるFacebookの使用を禁止し、8月1日までにアカウントを削除するよう指示した。

BTS

(2020年8月17日). 2026年4月16日時点のオリジナルよりアーカイブ。2026年4月16日閲覧。 ^ “韓国の芸能ニュースメディア・Dispatchの創立10周年を記念して韓国で開催された、グローバルK-POPフェスティバル「D'FESTA」。”. 2023年2月5日閲覧。 ^ “BTS NOW

ビッグ・テン男子バスケットボール最優秀選手賞

com/image/13505042 2024年1月21日閲覧。  ^ “Skiles tabbed Big 10 Player of the Year”. The York Dispatch (York, Pennsylvania): p. 15. (1986年3月11日). https://www.newspapers.com/image/614977580