多相型、推論、Ruby

1fab9d01b25e99522f3dfd01e3d4cb51?s=47 Soutaro Matsumoto
March 20, 2017
5.6k

 多相型、推論、Ruby

大江戸Ruby会議06 https://asakusarb.github.io/oedo06/

1fab9d01b25e99522f3dfd01e3d4cb51?s=128

Soutaro Matsumoto

March 20, 2017
Tweet

Transcript

  1. ଟ૬ܕɺ ਪ࿦ɺ Ruby দຊफଠ࿠
 @soutaro

  2. None
  3. None
  4. ܕ͸ॻ͖ͨ͘ͳ͍

  5. ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠

  6. ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦

  7. ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠

  8. ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍

  9. ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing

  10. ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨ Ruby͕ཉ͍͠ ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing

  11. զʑ͕ཉ͍͠΋ͷ ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby

  12. ଟ૬ܕ w ύϥϝʔλଟ૬Parametric Polymorphism w ෦෼ܕଟ૬Subtyping Polymorphism w ΞυϗοΫଟ૬Ad-hoc Polymorphism

    จ຺ʹԠͯ͡ɺҰఆͷ੍ݶͷݩͰɺ
 ࣜʹ͍Ζ͍ΖͳܕΛ༩͑Δ
  13. ෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X {

    void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList());
  14. ෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X {

    void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); Ҿ਺ͷܕ͸String
  15. ෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X {

    void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); Ҿ਺ͷܕ͸String Ҿ਺ͷܕ͸ArrayList
  16. ໊લతɾߏ଄త w ໊લతNominal
 ΫϥεఆٛͰએݴͯ͠෦෼ܕؔ܎Λఆٛ w ߏ଄తStructual
 ϝιουఆٛͷแؚؔ܎Ͱ෦෼ܕؔ܎ΛఆٛʢΑΓ ॊೈʣ

  17. ܕਪ࿦ w ʢ׬શͳʣܕਪ࿦ w ϩʔΧϧܕਪ࿦

  18. ʢ׬શͳʣܕਪ࿦ [Milner, 1978] w શ͘ܕΛॻ͔ͳͯ͘΋ྑ͍
 ʢܕਪ࿦ͷ׬શੑCompletenessʣ w ϓϩάϥϛϯάݴޠ΁ͷ੍໿͕େ͖͍ʢMLʣ # let

    has_even_leaf tree = exists_leaf (fun n -> n mod 2 = 0) tree;; val has_even_leaf : tree -> bool = <fun>
  19. ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func

    greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting }
  20. ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func

    greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕ͸ਪ࿦͞ΕΔ
  21. ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func

    greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕ͸ਪ࿦͞ΕΔ ؔ਺ͷܕ͸ॻ͘
  22. զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠

  23. OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby # let f x

    = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit = <fun>
  24. OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby # let f x

    = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit = <fun> #Ͱϝιουݺͼग़͠
  25. OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby # let f x

    = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit = <fun> to_sͱ͍͏ϝιου͕͋Ε͹ͳΜͰ΋͍͍ #Ͱϝιουݺͼग़͠
  26. OCamlͰ͸μϝͳͱ͜Ζ w OCaml΋ΦϒδΣΫτͷपΓͰ͸ܕΛॻ͘ඞཁ͕ ͋Δ w OCamlͰ͸ॻ͚ͳ͍ϝιου w Array#map String#split

  27. զʑ͕ཉ͍͠΋ͷ w ·ʔແཧ
 ͳʹ͔ΛఘΊͳ͍ͱ͍͚ͳ͍ɻ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby

  28. զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby

  29. զʑ͕ཉ͍͠΋ͷ RubyͷػೳΛ੍ݶ͍ͯͬͯ͠ɺܕਪ࿦Ͱ͖ ΔΑ͏ʹͳΒͳ͍͔ʁʁ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby

  30. eval w ແཧ w evalͷฦΓ஋ͷܕ͸anyΈ͍ͨͳܕʹͯ͠͠·͑͹ ͍͍ͷͰ͸ʢGradual Typing [Siek and Taha,

    2006]ʣ eval(gets)
  31. ActiveRecord w DBʹ઀ଓ͠ͳ͍ͱΞτϦϏϡʔτ͕Θ͔Βͳ͍ w anyͰͳΜͱ͔͠Α͏ class Person < ApplicationRecord belongs_to

    :group has_many :contacts end
  32. ϝλϓϩάϥϛϯά define_method(:name=) do |x| @attributes[:name] = x end

  33. ϝλϓϩάϥϛϯά class Location attr_reader :line attr_reader :column end

  34. require w require͕࣮ߦ͞ΕΔॠؒ·ͰͲͷϓϩάϥϜ͕ಡ· ΕΔ͔Θ͔Βͳ͍ w require͸ϝιουͳͷͰɺ࠶ఆٛͰ͖Δ͠ɺͲ͜ ʹͰ΋ॻ͚Δ͠ɺҾ਺ʹ͕ࣜॻ͚Δ w $LOAD_PATH΋͋ΔΑʂ w

    requireΛߏจʹͯ͠จࣈྻ͔͠ड͚औΕͳ͍ˍτο ϓϨϕϧʹ͔͠ॻ͚ͳ͍Α͏ʹ͢Ε͹ྑ͍ͷͰ͸
  35. RubyGems ⚰Bundler

  36. RubyΛ੍ݶͯ͠΋͏·͍͔͘ͳ͍ w ଞʹ΋໰୊͕͋Γɺݱ࣮తͳ੍ݶ͕ݟ͚ͭΒΕͳ͍ ʢࠓޙɺݟ͔ͭΔ͔΋͠Εͳ͍ʣ w ܕΛॻ͔ͳ͍લఏͰ͸ɺҰճanyʹࣦΘΕͨܕ৘ใ ΛऔΓ໭͢ํ๏͕ͳ͍

  37. զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ ߏ଄తͳ෦෼ܕଟ૬
  ׬શͳܕਪ࿦ Ruby

  38. ͝ఏҊ w ߏ଄తͳ෦෼ܕଟ૬ ϩʔΧϧܕਪ࿦ Gradual Typing w ʢΘΓͱʣDuck TypingͰ͖ΔͷͰخ͍͠ w

    ॻ͔ͳͯ͘ྑ͍ܕ͸ॻ͔ͳ͍ w ܕ͕ॻ͍ͯͳ͍ͱ͖͸ࠓͷRubyͱಉ͡ w ܕͷͨΊͷݴޠ͸Rubyͱผ
 requireͱ͔ΦʔϓϯΫϥεͱ͔ϝλϓϩάϥϛϯάͱ ͔͸ߟ͑ͳ͍ɻ
  39. ͍͍ͩͨTypeScript

  40. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … }
  41. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
  42. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
  43. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
  44. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
  45. # group.rbi interface String def gsub: (Regexp, String) -> String

    end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ person.emailͷܕ͕StringͩͱΘ ͔ΔͷͰɺmap͕ͳ͍͜ͱ͕Θ͔Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
  46. ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =

    person.email.map {|x| … }
  47. ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =

    person.email.map {|x| … } ܕ஫ऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿ΋ݕࠪ͠ͳ͍
  48. ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =

    person.email.map {|x| … } map͕ແ͍͜ͱ͸࣮ߦ࣌ʹൃ֮ ܕ஫ऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿ΋ݕࠪ͠ͳ͍
  49. # group.rbi interface String def gsub: (Regexp, String) -> String

    ... end interface IGroup def people: ActiveRecord.Association<IPerson> end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … }
  50. – Rubyͷ෕Matz lܕ͸ઈରॻ͖ͨ͘ͳ͍z

  51. w Group.create!ͷܕ͕GroupʹͳΔͷ͸Θ͔Βͳ͍ͷʁ
 Groupͷܕ͕Θ͔ΔͱࢥͬͯΔͷʁʁ w ܕΛҰͭ΋ॻ͍͍ͯͳ͍ͱͳʹ΋Θ͔Βͳ͍ͷʁʁ
 ϦςϥϧͳΜ͔͸Θ͔Δ͸ͣɻҙ֎ͱ͍Ζ͍Ζݟ͔ͭΔͷͰ͸ɻ w Ϋϥεఆٛʹ͸ܕΛॻ͚ͳ͍ͷʁΦʔϓϯΫϥε͸Ͳ͏ͳΔͷʁ
 ࠓޙͷ՝୊ɻΦʔϓϯΫϥεͱ0CKFDUJWF$ͷ$BUFHPSZͳΜ͔ ͸͍ۙؾ͕͢Δɻ

    w ࣮૷͸ͳ͍ͷʁ
 Α͘ݟΔͱɺʢܕ஫ऍΛίϝϯτͱ͔Ͱॻ͘͜ͱʹ͢Ε͹ʣ͙͢ ʹ࣮૷Ͱ͖Δͳ͜Εʜʜ