Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

DuckTyping

こんな基準でどうか。用語には自信ありません

  • クラス(or 型) X のインスタンスを Duck のように振る舞わせたいとき…
    • intrusive:X を定義するときに一緒に "X は Duck っぽい" と明記する
      • 例: class X implements Duck { ... }
    • nonintrusive-explicit: 外付けで "XはDuckっぽい" と明記する
      • 例: (ある場所で) data X = ... (別のところで) instance Duck X where ...
    • nonintrusive-implicit: 明記しない。普通 duck typing と言うとこれ。特に dynamic なものを指す。
      • 例: template<typename X> void foo(X x) { x.like_a_duck(); }
    • dynamic: 特定のメソッドを持った異なる種類のオブジェクトを実行時にいっしょくたに扱える
      • 例: pets=[Dog.new, Cat.new, Bear.new]; pets.each{|pet| pet.speak}
    • static: 扱えない
    • typed: 実際にはDuck的でないXをDuckっぽく使おうとすると静的なエラー
    • untyped-safe: 実際にはDuck的でないXをDuckっぽく使おうとすると実行時エラー
    • untyped-unsafe: 実際にはDuck的でないXをDuckっぽく使おうとすると、何がおきるかわからない
    • specialsyntax: 普通のメソッド呼び出しとは違った記法になる
      • 例: obj.speak() vs obj.getClass().getMethod("speak").invoke(obj)
    • normalsyntax: 普通のメソッド呼び出しと同じ記法
    • first-order: 呼び出すメソッドを値として操作できない
      • obj.to_s()
    • higher-order: 呼び出すメソッドを値として操作できる
      • obj.__send__([:to_s, :to_i][(rand*2).to_i])
  • 審議中
    ∧,,∧  ∧,,∧
 ∧ (´・ω・) (・ω・`) ∧∧
( ´・ω) U) ( つと ノ(ω・` )
| U (  ´・) (・`  ) と ノ
 u-u (l    ) (   ノu-u
     `u-u'. `u-u' 
intrusive-dynamic
継承 (特に Java, C#, ...)
intrusive-static
C++ の CRTP?(静的型言語での)mixin?
nonintrusive-explicit-dynamic
structural subtyping(型推論なし)。Haskellの存在型+型クラス http://www.haskell.org/haskellwiki/Existential_type、C の void* とか?、interfaceに適合させるラッパを手書きして継承とか?
nonintrusive-explicit-static
Haskell の型クラス。C++0x の explicit concept。Scalaのimplicit conversion/parameter。
nonintrusive-implicit-dynamic
いわゆる duck typing。structural subtyping(型推論あり)。静的言語の reflection?
nonintrusive-implicit-static
C++/D のテンプレート。 C のマクロ。
langintrusive-dynamicnonintrusive-explicit-staticnonintrusive-implicit-dynamicnonintrusive-implicit-static
C++継承すれば。但し primitive 型/標準ライブラリは不可void* / RTTIでがんばる / 関数ポインタなしtemplate
Java継承。但し primitive 型は不可なしreflectionなし
OOスクリプト言語なしなしduck typingなし
HaskellPhantom type(幽霊型)を使って模倣実例型クラスなしTemplateHaskell??
OCaml継承Obj.magic でがんばるstructural subtypingなんかありそうな気もする
Scala継承implicit conversion/parameterstructural subtypingなし
Ada継承generic / 関数ポインタなしなし
Delphi継承関数ポインタRTTI次のバージョンからtemplate入るらしい
Objective-C継承関数ポインタ非形式プロトコル#defineでがんばる
Goなし関数ポインタinterfaceなし
Rustなしtraitなしマクロで

intrusive / nonintrusive-explicit / nonintrusive-implicit × static / dynamic

-intrusivenonintrusive-explicitnonintrusive-implicit
static C++(void*, RTTI, 関数ポインタ), Haskell(型クラス), OCaml(Obj.magic), Scala(implicit conversion/parameter)C++(template), Haskell(TemplateHaskell??), OCaml(できそう)
dynamicC++(継承), Java(継承), Haskell(できそう), Scala(継承)Haskell(存在型+型クラス)Java(reflection), LL(duck typing), OCaml(structural subtyping), Scala(structural subtyping)

intrusive / nonintrusive-explicit / nonintrusive-implicit × typed / untyped

-intrusivenonintrusive-explicitnonintrusive-implicit
typedC++(継承), Java(継承), Haskell(できそう), Scala(継承), OCaml(継承)Haskell(型クラス), Scala(implicit conversion/parameter)C++(template), Haskell(TemplateHaskell??), OCaml(structural subtyping, できそう), Scala(structural subtyping)
untyped-safeJava(reflection), LL(duck typing)
untyped-unsafeC++(void*, RTTI, 関数ポインタ), OCaml(Obj.magic)
  • static / dynamicとuntyped / typedの関連がいまいち良くわからない
  • 直感的には、
    • 違う型の要素をcoersionして同じ型に揃えるのがdynamic
    • 違う型の要素は揃えられないといってリジェクトするのがstatic
  • じゃないかと思うんだけど、そうすると、typed / untypedの概念と関連がないと変な気がする
  • untypedなら、必ずdynamicが可能。一方、typedでdynamicをやろうとすると C++なら基底クラスを使ってexplicit-intrusiveにやるしかない(多分)。 一方、OCamlだとstructural subtypingのおかげでimplicit-nonintrusiveにできる / Haskellだと型クラス(と存在型のおかげで)non-intrusiveにできるが、型クラスなので(structuralでないので)explicit。
  • わかりました。私が考えていたのは、untyped && dynamic / typed && non-static / typed && staticという軸が考えられるのではないかということです。static / dynamicの定義は、一番上に書いてある例では型システムの制限なので、typed / untypedの軸に含めても良いような気がします。
    • なるほど。dynamicという言葉が適切ではないのかも。 ここのdynamicは「ヘテロなコレクションが可能」という意味ですよね。 あんまりstatic/dynamicという感じではない。 ところで non-static=dynamic?
      • わ、すみません。dynamicのつもりです。
Last modified:2016/09/09 01:54:43
Keyword(s):
References:[FrontPage] []