Monimenetelmä

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 5. tammikuuta 2015 tarkistetusta versiosta . tarkastukset vaativat 29 muokkausta .

Multimethod ( englanniksi  multimethod ) tai multiple dispatch ( englanniksi  multiple dispatch ) on ohjelmointikielien mekanismi, jonka avulla voit valita yhden useista toiminnoista riippuen dynaamisista tyypeistä tai argumenttiarvoista (esimerkiksi menetelmän ylikuormitus joissakin ohjelmointikielissä) . Se on yksittäisen lähetyksen ( virtuaalifunktiot ) laajennus, jossa menetelmän valinta tehdään dynaamisesti sen kohteen todellisen tyypin perusteella, johon menetelmää kutsuttiin. Multiple dispatch yleistää dynaamisen lähettämisen tapauksissa, joissa on kaksi tai useampia objekteja.

"Common Lisp Object System" ( CLOS ) tukee monimenetelmiä .

Lähetyksen perusteet

Ohjelmakehittäjillä on tapana ryhmitellä lähdekoodi nimettyihin lohkoihin, joita kutsutaan kutsuiksi, proseduureiksi, aliohjelmiksi , funktioiksi tai menetelmiksi. Toiminnon koodi suoritetaan kutsumalla sitä, mikä koostuu sen nimen osoittaman koodinpalan suorittamisesta. Tässä tapauksessa ohjaus siirretään tilapäisesti kutsutulle funktiolle; kun tämä toiminto on valmis, ohjaus siirtyy yleensä takaisin funktiokutsua seuraavalle käskylle.

Toimintojen nimet valitaan yleensä kuvaamaan niiden tarkoitusta. Joskus on tarpeen nimetä useita toimintoja samalla nimellä, yleensä koska ne suorittavat käsitteellisesti samanlaisia ​​tehtäviä, mutta toimivat erityyppisten syöttötietojen kanssa. Tällaisissa tapauksissa funktion nimi sen kutsupaikassa ei riitä määrittämään kutsuttavan koodilohkon. Nimen lisäksi tässä tapauksessa käytetään myös kutsutun funktion argumenttien määrää ja tyyppiä funktion tietyn toteutuksen valitsemiseen.

Perinteisemmissä yhden lähetyksen olioohjelmointikielissä, kun menetelmää kutsutaan (viestin lähettäminen Smalltalkissa , jäsenfunktion kutsuminen C++ :ssa ), yhtä sen argumenteista käsitellään erityisellä tavalla ja sen avulla määritetään, mikä mahdollisesti monia) menetelmiä tällä nimellä on kutsuttava. Monissa kielissä tämä erityinen argumentti ilmaistaan ​​syntaktisesti, esimerkiksi useissa ohjelmointikielissä erityinen argumentti asetetaan ennen pistettä, kun menetelmää kutsutaan:

erikoismenetelmä (muut, argumentit, tässä)

joten lion.sound() tuottaa karjun ja sparrow.sound() tuottaa sirkutuksen.

Sitä vastoin kielissä, joissa on useita lähetyksiä, valittu menetelmä on yksinkertaisesti menetelmä, jonka argumentit vastaavat funktiokutsussa olevien argumenttien määrää ja tyyppiä. Tässä ei ole mitään erityistä argumenttia, joka "omistaa" tietyn kutsun viittaaman funktion tai menetelmän.

Common Lisp Object System (CLOS) on yksi ensimmäisistä ja tunnetuista useiden lähetysten toteutuksista.

Tietotyypit

Kun työskentelet sellaisten kielten kanssa, joiden tietotyypit erotetaan käännöshetkellä, valinta käytettävissä olevista toimintovaihtoehdoista voi tapahtua käännöshetkellä. Tällaisten vaihtoehtoisten funktiovaihtoehtojen luomista käännöshetkellä kutsutaan yleisesti funktion ylikuormitukseksi .

Ohjelmointikielissä, jotka määrittävät tietotyypit ajon aikana (myöhäinen sidonta), toimintovaihtoehtojen valinnan on tapahduttava ajon aikana dynaamisesti määritettyjen funktion argumenttityyppien perusteella. Funktioita, joiden vaihtoehtoiset toteutukset valitaan tällä tavalla, kutsutaan yleisesti multimetodeiksi.

Toimintokutsujen dynaamiseen lähettämiseen liittyy joitain ajonaikaisia ​​kustannuksia. Joissakin kielissä ero funktion ylikuormituksen ja monimenetelmien välillä voi hämärtyä, kun kääntäjä määrittää, voidaanko kutsutun funktion valinta tehdä käännösvaiheessa vai tarvitaanko hitaampaa lähetystä ajon aikana.

Käytännön käyttö

Arvioidakseen kuinka usein monivälitystä käytännössä käytetään, Muschevici ym . [1] tutkivat sovelluksia, jotka käyttävät dynaamista jakelua. He analysoivat yhdeksää sovellusta, enimmäkseen kääntäjiä, jotka oli kirjoitettu kuudella eri ohjelmointikielellä: Common Lisp Object System , Dylan , Cecil, MultiJava, Diesel ja Nice. Tulokset osoittavat, että 13–32 % yleisistä funktioista käyttää yhden argumentin dynaamista kirjoitusta, kun taas 2,7–6,5 % funktioista käyttää usean argumentin dynaamista kirjoitusta. Loput 65–93 % yleisistä funktioista käyttävät vain tiettyä menetelmää (ylikuormitettu), joten niiden ei katsottu käyttävän argumenttien dynaamista tyyppiä. Lisäksi tutkimus raportoi, että 2–20 prosentilla yleisistä toiminnoista oli kaksi ja 3–6 prosentilla kolme erityistä toteutusta. Konkreettisia toteutuksia sisältävien toimintojen osuus oli nopeasti laskussa.

Teoria

Monen puhelun kielten teorian kehittivät ensimmäisenä Castagna ym. määrittelemällä mallin ylikuormitetuille funktioille myöhäisellä sidoksella [2] [3] . Tämä antoi ensimmäisen formalisoinnin olio-ohjelmointikielten kovarianssin ja vastavariaatioiden [4] ongelmalle ja ratkaisun binäärimenetelmien [5] ongelmaan .

Esimerkki

Jotta voitaisiin paremmin ymmärtää ero monimenetelmien ja kertalähetyksen välillä, voidaan havainnollistaa seuraava esimerkki. Kuvittele peli, jossa monien muiden esineiden ohella on asteroideja ja avaruusaluksia. Kun kaksi kohdetta törmäävät, ohjelman on valittava tietty toimintoalgoritmi sen mukaan, mikä törmäsi mihinkin.

Common Lisp

Monimenetelmäkielessä, kuten Common Lisp , koodi näyttäisi tältä:

( defgeneric törmäys ( x y )) ( defmethod törmää (( x asteroidi ) ( y asteroidi )) ;; asteroidi törmää asteroidiin ) ( defmethod törmää (( x asteroidi ) ( y avaruusalus )) ;;asteroidi törmää avaruusalukseen ) ( defmethod törmää (( x avaruusalus ) ( y asteroidi )) ;;avaruusalus törmää asteroidiin ) ( defmethod törmää (( x avaruusalus ) ( y avaruusalus )) ;;avaruusalus törmää avaruusalukseen )

ja samoin muille menetelmille. Eksplisiittistä tarkistusta ja "dynaamista suoraa" ei käytetä tässä. 

Useiden lähetysten yhteydessä perinteinen lähestymistapa luokkien menetelmien määrittämiseen ja niiden tallentamiseen objekteihin tulee vähemmän houkuttelevaksi, koska jokainen törmäysmenetelmä viittaa kahteen eri luokkaan yhden sijasta. Näin ollen menetelmän kutsumisen erityinen syntaksi yleensä katoaa, joten menetelmäkutsu näyttää täsmälleen normaalilta funktiokutsulta ja menetelmät eivät ryhmitetä luokkien mukaan, vaan yleisiin funktioihin .

Raku

Raku, kuten aiemmat versiot, käyttää todistettuja ideoita muista kielistä ja tyyppijärjestelmistä tarjotakseen vakuuttavia etuja kääntäjäpuolen koodianalyysissä ja tehokkaassa semantiikkassa useiden lähetysten avulla.

Siinä on sekä multimetodeja että monialirutiineja. Koska useimmat lausunnot ovat alirutiineja, on myös lauseita, joissa on useita lähetyksiä.

Tavallisten tyyppirajoitusten lisäksi siinä on myös "jos"-tyyppisiä rajoituksia, joiden avulla voit luoda erittäin erikoistuneita aliohjelmia.

osajoukko Realin massa missä 0 ^ ..^ Inf ; rooli Stellar-Object { has Mass $ .massa vaaditaan ; menetelmän nimi () palauttaa Str {...}; } luokan asteroidi tekee Stellar-Objectin { menetelmän nimi () { 'asteroidi' } } class Avaruusalus tekee Stellar-Objectin { has Str $.name = 'jokin nimetön avaruusalus' ; } my Str @detroyed = < hävitetty tuhottu mangled >; my Str @damaged = "  vaurioitunut 'törmäsi' 'vaurioitui'  "; # Lisäämme useita ehdokkaita numeerisiin vertailuoperaattoreihin, koska vertaamme niitä numeerisesti, # mutta ei ole järkevää pakottaa objektit numeeriseen tyyppiin. # (Jos he pakottaisivat, meidän ei välttämättä tarvitsisi lisätä näitä operaattoreita. ) # Olisimme voineet määritellä myös täysin uusia operaattoreita samalla tavalla. multi subinfix : " <=> " ( Tähti-objekti:D $a , tähti-objekti:D $b ) { $a . massa <=> $b . massa } moni aliliite : " < " ( Tähti-objekti:D $a , Tähti-objekti:D $b ) { $a . massa < $b . massa } moni aliliite : " > " ( Tähti-objekti:D $a , tähti-objekti:D $b ) { $a . massa > $b . massa } moni aliliite : " == " ( Tähti-objekti:D $a , tähti-objekti:D $b ) { $a . massa == $b . massa } # Määrittele uusi monivälittäjä ja lisää parametreihin joitain tyyppirajoituksia. # Jos emme olisi määrittäneet sitä, olisimme saaneet yleisen, jolla ei ole rajoituksia. proto - alitörmäys ( tähti -objekti:D $, tähti-objekti:D $ ) {*} # Tyyppejä ei tarvitse toistaa tässä, koska ne ovat samat kuin prototyyppi. # 'where' -rajoitus koskee teknisesti vain $b:tä, ei koko allekirjoitusta. # Huomaa, että "where" -rajoite käyttää aiemmin lisäämäämme "<"-operaattoriehdokasta. monen osatörmäys ( $a , $b jossa $a < $b ) { sano "$b.name() @tuhoittui.nimi() " ; } monen osatörmäys ( $a , $ b jossa $a > $b ) { # uudelleenlähetys edelliselle ehdokkaalle argumenteilla, jotka on vaihdettu samaan kanssa $b , $a ; } # Tämän täytyy olla kahden ensimmäisen jälkeen, koska muilla # on "minne"-rajoitukset, jotka tarkistetaan siinä # järjestyksessä, jossa subs kirjoitettiin. (Tämä sopisi aina yhteen. ) Multi sub törmää ( $a , $b ){ # satunnaista järjestys my ( $n1 , $n2 ) = ( $a . nimi , $b . nimi ). valita (*); sano "$n1 @damaged.pick() $n2" ; } # Seuraavat kaksi ehdokasta voivat olla missä tahansa proton jälkeen, # koska niillä on erikoistuneempia tyyppejä kuin kolme edellistä. # Jos alusten massa on epätasainen, toinen kahdesta ensimmäisestä ehdokkaasta kutsutaan tilalle. usean osatörmäyksen ( Avaruusalus $a , Avaruusalus $ b jossa $ a == $b ){ minun ( $n1 , $n2 ) = ( $a . nimi , $b . nimi ). valita (*); sano "$n1 törmäsi $n2:een ja molemmat alukset olivat " , ( @detroyed . pick , 'vasen vahingoittunut' ). valita ; } # Voit purkaa määritteet muuttujiksi allekirjoituksen sisällä. # Voit jopa asettaa niille rajoituksen `(:mass($a) missä 10)`. moniosatörmäys ( Asteroidi $ (: massa ( $a )), Asteroidi $ (: massa ( $b ))){ sano "kaksi asteroidia törmäsivät ja yhdistyivät yhdeksi suuremmaksi asteroidiksi, jonka massa on { $a + $b }" ; } minun avaruusalus $Enterprise .= uusi (: massa ( 1 ),: nimi ( 'The Enterprise' )); törmää asteroidiin . uusi (: massa ( .1 )), $Enterprise ; törmää $Enterprise , avaruusalus . uusi (: massa ( .1 )); törmäävät $Enterprise , Asteroidi . uusi (: massa ( 1 )); törmää $Enterprise , avaruusalus . uusi (: massa ( 1 )); törmää asteroidiin . uusi (: massa ( 10 )), Asteroidi . uusi (: massa ( 5 ));

Python

Kielessä, joka ei tue useaa lähetystä syntaksitasolla, kuten Python , on yleensä mahdollista käyttää useaa lähetystä laajennuskirjastojen avulla. Esimerkiksi multimethods.py-moduuli [6] toteuttaa CLOS-tyylisiä monimenetelmiä Pythonissa muuttamatta syntaksia tai kielen avainsanoja.

multimethods -tuonti Lähettäminen game_objects - tuonnista Asteroidi , Avaruusalus from game_behaviors tuonti ASFunc , SSFunc , SAFunc törmää = Lähetys ( ) törmää . add_rule (( Asteroidi , Avaruusalus ), ASFunc ) törmää . add_rule (( avaruusalus , avaruusalus ), SSFunc ) törmää . add_rule (( Avaruusalus , Asteroidi ), SAFunc ) def AAFunc ( a , b ): """Käyttäytyminen asteroidin osuessa asteroidiin""" # ...määrittää uusi käyttäytyminen... törmää . add_rule (( Asteroidi , Asteroidi ), AAFunc ) # ...myöhemmin... törmää ( asia1 , asia2 )

Toiminnallisesti tämä on hyvin samanlainen kuin CLOS-esimerkki, mutta syntaksi noudattaa standardi Python-syntaksia.

Käyttämällä Python 2.4 -dekoraattoreita Guido van Rossum kirjoitti esimerkin monimetodeista [7] yksinkertaistetulla syntaksilla:

@multimethod ( Asteroid , Asteroid ) def törmäys ( a , b ): """Käyttäytyminen asteroidin osuessa asteroidiin""" # ...määritä uusi käyttäytyminen... @multimethod ( Asteroid , Asteroid ) def törmäys ( a , b ) : """Käyttäytyminen asteroidin osuessa avaruusalukseen""" # ...määritä uusi käyttäytyminen... # ... määritä muut monimenetelmäsäännöt ...

ja sitten määritellään sisustajan monimenetelmä.

PEAK-Rules-paketti toteuttaa usean lähettämisen syntaksilla, joka on samanlainen kuin yllä oleva esimerkki. [kahdeksan]

Multiple dispatch emulation

Java

Kieleillä, joilla on vain yksi lähetys, kuten Java , tämä koodi näyttää tältä ( vierailijamalli voi kuitenkin auttaa ratkaisemaan tämän ongelman):

/* Esimerkki suoritusaikatyyppivertailusta Javan "instanceof"-operaattorilla */ käyttöliittymä Collideable { /* Tämän luokan tekeminen ei muuttaisi esittelyä. */ void collideWith ( Collideable other ); } luokan Asteroidi toteuttaa Collideable { public void törmätäWith ( Collideable other ) { if ( other instanceof Asteroid ) { // Käsittele asteroidin ja asteroidin törmäystä. } else if ( avaruusaluksen muu esiintymä ) { // Käsittele asteroidi-avaruusaluksen törmäystä. } } } luokan avaruusalus toteuttaa Collideable { public void törmätäWith ( Collideable other ) { if ( other instanceof Asteroid ) { // Käsittele avaruusaluksen ja asteroidin törmäystä. } else if ( other instanceof Spaceship ) { // Käsittele avaruusalus-avaruusaluksen törmäystä. } } }

C

C:llä ei ole dynaamista lähetystä, joten se täytyy toteuttaa käsin muodossa tai toisessa. Luetteloa käytetään usein tunnistamaan objektin alatyyppi. Dynaaminen lähetys voidaan toteuttaa etsimällä tämä arvo toimintoosoittimien haarataulukosta. Tässä on yksinkertainen esimerkki C:ssä:

typedef void ( * CollisionCase )(); void collision_AA () { /* Asteroidin ja asteroidin törmäyksen käsittely */ }; void collision_AS () { /* Asteroidi-laivan törmäyksen käsittely */ }; void collision_SA () { /* Aluksen ja asteroidin törmäyksen käsittely */ }; void collision_SS () { /* alusten välisten törmäysten käsittely */ }; typedef enum { asteroidi = 0_ _ avaruusalus , num_thing_types /* ei ole objektityyppi, sitä käytetään objektien lukumäärän etsimiseen */ } Asia ; CollisionCase collisionCases [ num_thing_types ][ num_thing_types ] = { { & collision_AA , & collision_AS }, { & collision_SA , & collision_SS } }; void törmää ( asia a , asia b ) { ( * törmäystapaukset [ a ][ b ])(); } int main () { törmätä ( avaruusalus , asteroidi ); }

C++

Vuodesta 2015 lähtien C++ tukee vain yksittäistä lähetystä, vaikka useiden lähetysten tukea harkitaan. [9]  Tämän rajoituksen kiertotavat ovat samanlaiset: joko vierailijamallin tai dynaamisen suoratoiston avulla:

// Esimerkki suoritusajan tyyppivertailusta dynamic_castin avulla struct Thing { virtuaalinen void törmätä ( asia ja muu ) = 0 ; }; rakenne Asteroidi : Asia { void collideWith ( asia ja muut ) { // dynaaminen_cast osoitintyyppiin palauttaa NULL-arvon, jos heitto epäonnistuu // (dynaaminen_lähetys viitetyyppiin aiheuttaisi poikkeuksen epäonnistumisen yhteydessä) if ( Asteroid * asteroid = dynaaminen_cast < Asteroid *> ( & other )) { // käsittele asteroidin ja asteroidin törmäystä } else if ( Avaruusalus * avaruusalus = dynaaminen_cast < Avaruusalus *> ( & muu )) { // käsittele asteroidin ja avaruusaluksen törmäystä } else { // oletusarvoinen törmäyskäsittely täällä } } }; struct Avaruusalus : Thing { void collideWith ( asia ja muut ) { if ( Asteroidi * asteroidi = dynaaminen_cast < Asteroid *> ( & muu )) { // käsittele avaruusaluksen ja asteroidin törmäystä } else if ( Avaruusalus * avaruusalus = dynaaminen_cast < Avaruusalus *> ( ja muut )) { // käsittele avaruusaluksen ja avaruusaluksen törmäystä } else { // oletusarvoinen törmäyskäsittely täällä } } };

tai hakutaulukot menetelmiin viittaaville:

#include <tyyppitiedot> #include <järjestämätön_kartta> typedef allekirjoittamaton uint4 ; typedef unsigned pitkä pitkä uint8 ; luokka asia { suojattu : Asia ( const uint4 cid ) : tid ( cid ) {} const uint4 tid ; // kirjoita id typedef void ( Thing ::* CollisionHandler )( Thing & muu ); typedef std :: unordered_map < uint8 , CollisionHandler > CollisionHandlerMap ; static void addHandler ( const uint4 id1 , const uint4 id2 , const CollisionHandler käsittelijä ) { törmäystapaukset . insert ( CollisionHandlerMap :: arvo_tyyppi ( avain ( id1 , id2 ), käsittelijä )); } staattinen uint8 avain ( const uint4 id1 , const uint4 id2 ) { palauttaa uint8 ( id1 ) << 32 | id2 ; } staattinen CollisionHandlerMap collisionCases ; julkinen : void collideWith ( asia ja muut ) { CollisionHandlerMap :: const_iterator handler = törmäystapaukset . löytää ( avain ( tid , muu . tid )); if ( käsittelijä != törmäysCases . end ()) { ( tämä ->* käsittelijä -> toinen )( muu ); // pointer-to-method call } else { // oletus törmäyskäsittely } } }; luokan asteroidi : julkinen asia { void asteroid_collision ( Thing & other ) { /*handle Asteroid-Asteroid Collision*/ } void spaceship_collision ( Thing & other ) { /*käsitellä asteroidi-avaruusaluksen törmäystä*/ } julkinen : Asteroidi () : Asia ( cid ) {} static void initCases (); staattinen const uint4 cid ; }; luokan avaruusalus : julkinen asia { void asteroid_collision ( Thing & other ) { /*käsitellä avaruusaluksen ja asteroidin törmäystä*/ } void spaceship_collision ( Thing & other ) { /*handle Spaceship-Spaceship collision*/ } julkinen : Avaruusalus () : Asia ( cid ) {} static void initCases (); staattinen const uint4 cid ; // luokan tunnus }; Asia :: CollisionHandlerMap Thing :: collisionCases ; const uint4 Asteroidi :: cid = typeid ( Asteroid ). hash_code (); const uint4 Avaruusalus :: cid = typeid ( Spaceship ). hash_code (); void Asteroid::initCases () { addHandler ( cid , cid , ( CollisionHandler ) & Asteroid :: asteroid_collision ); addHandler ( cid , Spaceship :: cid , ( CollisionHandler ) & Asteroid :: spaceship_collision ); } void Spaceship::initCases () { addHandler ( cid , Asteroid :: cid , ( CollisionHandler ) & avaruusalus :: asteroid_collision ); addHandler ( cid , cid , ( CollisionHandler ) & Spaceship :: spaceship_collision ); } int main () { Asteroidi :: initCases (); avaruusalus :: initCases (); asteroidi a1 , a2 ; avaruusalus s1 , s2 ; a1 . törmää ( a2 ); a1 . törmätä kanssa ( s1 ); s1 . törmätä ( s2 ); s1 . törmää ( a1 ); }

Yomm11-kirjasto [10] mahdollistaa tämän lähestymistavan automatisoinnin.

Kirjassaan The Design and Evolution of C++ Stroustrup mainitsee, että hän pitää monimenetelmien käsitteestä ja että hän harkitsi niiden toteuttamista C++:ssa, mutta väittää, ettei hän löytänyt esimerkkiä tehokkaasta (verrattuna) virtuaalisiin toimintoihin. ja ratkaise joitakin mahdollisia tyyppien epäselvyysongelmia. Hän väittää lisäksi, että vaikka olisi mukavaa ottaa käyttöön tuki tälle konseptille, se voidaan approksimoida kaksoislähetyksellä tai tyyppipohjaisella hakutaulukolla, kuten yllä olevassa C/C++-esimerkissä on kuvattu, joten tämä tehtävä on kehitystyössä alhainen prioriteetti. kielen tulevista versioista. [yksitoista]

Toteutus ohjelmointikielillä

Tuki monimuotoisille menetelmille muilla kielillä laajennusten kautta:

Haskellin ja Scalan moniparametrityyppisiä luokkia  voidaan käyttää myös monimenetelmien emulointiin.

Muistiinpanot

  1. Muschevici, Radu; Potanin, Aleksi; Tempero, Ewan; Noble, James (2008). "Useita lähetyksiä käytännössä" . Olio-ohjelmointijärjestelmien kieliä ja sovelluksia käsittelevän 23. ACM SIGPLAN -konferenssin julkaisut . OOPSLA '08 (Nashville, TN, USA: ACM): 563–582
  2. Giuseppe Castagna; Giorgio Ghelli ja Giuseppe Longo (1995). "Lasku ylikuormitetuille funktioille alatyypeillä." Arkistoitu 18. marraskuuta 2018 Wayback Machinessa . Informaatio ja laskenta  (Akateeminen lehdistö)  117  (1): 115–135
  3. Castagna, Giuseppe (1996). Olio-ohjelmointi: Unified Foundation . Birkhauser. s. 384.
  4. Giuseppe Castagna (1995). "Kovarianssi ja kontravarianssi: konflikti ilman syytä" Arkistoitu 20. marraskuuta 2018 Wayback Machinessa . Transactions on Programming Languages ​​and Systems (TOPLAS)  (ACM)  17  (3). doi : 10.1145/203095.203096
  5. Kim Bruce; Luca Cardelli; Giuseppe Castagna; Gary T. Leavens; Benjamin Pierce (1995). "Binäärimenetelmistä" Arkistoitu 19. marraskuuta 2018 Wayback Machinessa . Oliojärjestelmien teoria ja käytäntö  1  (3)
  6. multimethods.py Arkistoitu 9. maaliskuuta 2005 Wayback Machinessa , Multiple dispatch in Python konfiguroitavalla lähetysresoluutiolla David Mertz et al.
  7. Viiden minuutin multimetodit Pythonissa . Haettu 16. heinäkuuta 2016. Arkistoitu alkuperäisestä 29. toukokuuta 2021.
  8. "PEAK-Rules 0.5a1.dev" Arkistoitu 14. maaliskuuta 2017 Wayback Machinessa . Python-pakettihakemisto . Haettu 21. maaliskuuta 2014.
  9. Arkistoitu kopio . Haettu 16. heinäkuuta 2016. Arkistoitu alkuperäisestä 17. maaliskuuta 2016.
  10. yomm11 Arkistoitu 2. kesäkuuta 2016 Wayback Machinessa , Jean-Louis Leroyn Open Multi-Methods for C++11.
  11. Stroustrup, Bjarne (1994). Kohta 13.8. C++:n suunnittelu ja kehitys . Indianapolis, IN, USA: Addison Wesley. ISBN  0-201-54330-3 .
  12. Steele, Guy L. (1990). luku 28. Yleinen LISP: The Language Arkistoitu 17. joulukuuta 2017 Wayback Machinessa . Bedford, MA, USA: Digital Press. ISBN  1-55558-041-6 .
  13. "Tyyppiluokat: suunnitteluavaruuden tutkiminen" Arkistoitu 12. elokuuta 2016 Wayback Machinessa . 1997-05-02.
  14. "Elixir Lang | Aloitus | Moduulit" Arkistoitu 20. heinäkuuta 2016 Wayback Machinessa . Haettu 21.2.2016.
  15. "Tausta ja tavoitteet" Arkistoitu 4. huhtikuuta 2020 Wayback Machinessa . Haettu 13.4.2008.
  16. "Visitor Pattern Versus Multimethods" Arkistoitu 5. helmikuuta 2021 Wayback Machinessa . Haettu 13.4.2008.
  17. "Cecil Language" Arkistoitu 1. syyskuuta 2016 Wayback Machinessa . Haettu 13.4.2008.
  18. "How S4 Methods Work" Arkistoitu 10. toukokuuta 2021 Wayback Machineen  (PDF). Haettu 13.4.2008.
  19. "Menetelmät" Arkistoitu 17. heinäkuuta 2016 Wayback Machinessa . Julian käsikirja . Julialang. Haettu 11.5.2014.
  20. "Multimethods in Groovy" Arkistoitu 12. elokuuta 2011 Wayback Machineen . Haettu 13.4.2008.
  21. "Methods - LassoGuide 9.2" Arkistoitu 13. kesäkuuta 2021 Wayback Machinessa . Haettu 11.11.2014.
  22. "Perl 6 FAQ" Arkistoitu 13. maaliskuuta 2012 Wayback Machinessa . Haettu 13.4.2008.
  23. "Multiple Dispatch in Seed7" Arkistoitu 29. tammikuuta 2021 Wayback Machinessa . Haettu 23.4.2011
  24. "Multimethods in Clojure" Arkistoitu 20. syyskuuta 2015 Wayback Machinessa . Haettu 2008-09-04.
  25. "Multimethods in C# 4.0 With 'Dynamic" Arkistoitu 25. elokuuta 2009 Wayback Machinessa . Haettu 20.08.2009.
  26. "The Fortress Language Specification, Version 1.0" Arkistoitu 20. tammikuuta 2013 Wayback Machinessa (PDF). Haettu 23.4.2010.
  27. "TADS 3 System Manual" Arkistoitu 14. helmikuuta 2017 Wayback Machinessa . Haettu 19.3.2012
  28. "Multiple dispatch" Arkistoitu 15. heinäkuuta 2016 Wayback Machinessa .
  29. "Nim Manual" Arkistoitu 24. syyskuuta 2017 Wayback Machinessa . Haettu 2015-05-08.