Upgrade to Pro — share decks privately, control downloads, hide ads and more …

多相型、推論、Ruby

Soutaro Matsumoto
March 20, 2017
6.5k

 多相型、推論、Ruby

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

Soutaro Matsumoto

March 20, 2017
Tweet

Transcript

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

    @soutaro

    View full-size slide

  2. ܕ͸ॻ͖ͨ͘ͳ͍

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    ׬શͳܕਪ࿦Ruby

    View full-size slide

  10. ଟ૬ܕ
    w ύϥϝʔλଟ૬Parametric Polymorphism
    w ෦෼ܕଟ૬Subtyping Polymorphism
    w ΞυϗοΫଟ૬Ad-hoc Polymorphism
    จ຺ʹԠͯ͡ɺҰఆͷ੍ݶͷݩͰɺ

    ࣜʹ͍Ζ͍ΖͳܕΛ༩͑Δ

    View full-size slide

  11. ෦෼ܕଟ૬
    w ෦෼ܕ

    “String is a Object”
    interface X {
    void f(Object x);
    }
    X x = …;
    x.f("Ruby");
    x.f(new ArrayList());

    View full-size slide

  12. ෦෼ܕଟ૬
    w ෦෼ܕ

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

    View full-size slide

  13. ෦෼ܕଟ૬
    w ෦෼ܕ

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

    View full-size slide

  14. ໊લతɾߏ଄త
    w ໊લతNominal

    ΫϥεఆٛͰએݴͯ͠෦෼ܕؔ܎Λఆٛ
    w ߏ଄తStructual

    ϝιουఆٛͷแؚؔ܎Ͱ෦෼ܕؔ܎ΛఆٛʢΑΓ
    ॊೈʣ

    View full-size slide

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

    View full-size slide

  16. ʢ׬શͳʣܕਪ࿦
    [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 =

    View full-size slide

  17. ϩʔΧϧܕਪ࿦
    [Pierce, 1997]
    w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍

    ϝιουͱ͔ͷܕ͸ॻ͘ɻ
    w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ

    ʢScala/Swift/C#/C++ʣ
    func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
    }

    View full-size slide

  18. ϩʔΧϧܕਪ࿦
    [Pierce, 1997]
    w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍

    ϝιουͱ͔ͷܕ͸ॻ͘ɻ
    w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ

    ʢScala/Swift/C#/C++ʣ
    func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
    } greetingͷܕ͸ਪ࿦͞ΕΔ

    View full-size slide

  19. ϩʔΧϧܕਪ࿦
    [Pierce, 1997]
    w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍

    ϝιουͱ͔ͷܕ͸ॻ͘ɻ
    w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ

    ʢScala/Swift/C#/C++ʣ
    func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
    } greetingͷܕ͸ਪ࿦͞ΕΔ
    ؔ਺ͷܕ͸ॻ͘

    View full-size slide

  20. զʑ͕ཉ͍͠΋ͷ
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby
    ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠

    View full-size slide

  21. OCamlͳΜ͔͍ۙͷͰ͸
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby
    # let f x = print_string x#to_s;;
    val f : < to_s : string; .. >

    -> unit =

    View full-size slide

  22. OCamlͳΜ͔͍ۙͷͰ͸
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby
    # let f x = print_string x#to_s;;
    val f : < to_s : string; .. >

    -> unit =
    #Ͱϝιουݺͼग़͠

    View full-size slide

  23. OCamlͳΜ͔͍ۙͷͰ͸
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby
    # let f x = print_string x#to_s;;
    val f : < to_s : string; .. >

    -> unit =
    to_sͱ͍͏ϝιου͕͋Ε͹ͳΜͰ΋͍͍
    #Ͱϝιουݺͼग़͠

    View full-size slide

  24. OCamlͰ͸μϝͳͱ͜Ζ
    w OCaml΋ΦϒδΣΫτͷपΓͰ͸ܕΛॻ͘ඞཁ͕
    ͋Δ
    w OCamlͰ͸ॻ͚ͳ͍ϝιου
    w Array#map String#split

    View full-size slide

  25. զʑ͕ཉ͍͠΋ͷ
    w ·ʔແཧ

    ͳʹ͔ΛఘΊͳ͍ͱ͍͚ͳ͍ɻ
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby

    View full-size slide

  26. զʑ͕ཉ͍͠΋ͷ
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby

    View full-size slide

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

    ׬શͳܕਪ࿦Ruby

    View full-size slide

  28. eval
    w ແཧ
    w evalͷฦΓ஋ͷܕ͸anyΈ͍ͨͳܕʹͯ͠͠·͑͹
    ͍͍ͷͰ͸ʢGradual Typing [Siek and Taha, 2006]ʣ
    eval(gets)

    View full-size slide

  29. ActiveRecord
    w DBʹ઀ଓ͠ͳ͍ͱΞτϦϏϡʔτ͕Θ͔Βͳ͍
    w anyͰͳΜͱ͔͠Α͏
    class Person < ApplicationRecord
    belongs_to :group
    has_many :contacts
    end

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. require
    w require͕࣮ߦ͞ΕΔॠؒ·ͰͲͷϓϩάϥϜ͕ಡ·
    ΕΔ͔Θ͔Βͳ͍
    w require͸ϝιουͳͷͰɺ࠶ఆٛͰ͖Δ͠ɺͲ͜
    ʹͰ΋ॻ͚Δ͠ɺҾ਺ʹ͕ࣜॻ͚Δ
    w $LOAD_PATH΋͋ΔΑʂ
    w requireΛߏจʹͯ͠จࣈྻ͔͠ड͚औΕͳ͍ˍτο
    ϓϨϕϧʹ͔͠ॻ͚ͳ͍Α͏ʹ͢Ε͹ྑ͍ͷͰ͸

    View full-size slide

  33. RubyGems
    ⚰Bundler

    View full-size slide

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

    View full-size slide

  35. զʑ͕ཉ͍͠΋ͷ
    ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬

    ׬શͳܕਪ࿦Ruby

    View full-size slide

  36. ͝ఏҊ
    w ߏ଄తͳ෦෼ܕଟ૬ϩʔΧϧܕਪ࿦Gradual Typing
    w ʢΘΓͱʣDuck TypingͰ͖ΔͷͰخ͍͠
    w ॻ͔ͳͯ͘ྑ͍ܕ͸ॻ͔ͳ͍
    w ܕ͕ॻ͍ͯͳ͍ͱ͖͸ࠓͷRubyͱಉ͡
    w ܕͷͨΊͷݴޠ͸Rubyͱผ

    requireͱ͔ΦʔϓϯΫϥεͱ͔ϝλϓϩάϥϛϯάͱ
    ͔͸ߟ͑ͳ͍ɻ

    View full-size slide

  37. ͍͍ͩͨTypeScript

    View full-size slide

  38. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }

    View full-size slide

  39. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }
    ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ

    View full-size slide

  40. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }
    ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
    ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

    View full-size slide

  41. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }
    ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
    ܕ஫ऍ
    ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

    View full-size slide

  42. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }
    ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
    ܕ஫ऍ
    ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ
    ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

    View full-size slide

  43. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    end
    interface IGroup
    def people: ActiveRecord.Association
    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͕ͳ͍͜ͱ͕Θ͔Δ
    ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  47. # group.rbi
    interface String
    def gsub: (Regexp, String) -> String
    ...
    end
    interface IGroup
    def people: ActiveRecord.Association
    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| … }

    View full-size slide

  48. – Rubyͷ෕Matz
    lܕ͸ઈରॻ͖ͨ͘ͳ͍z

    View full-size slide

  49. w Group.create!ͷܕ͕GroupʹͳΔͷ͸Θ͔Βͳ͍ͷʁ

    Groupͷܕ͕Θ͔ΔͱࢥͬͯΔͷʁʁ
    w ܕΛҰͭ΋ॻ͍͍ͯͳ͍ͱͳʹ΋Θ͔Βͳ͍ͷʁʁ

    ϦςϥϧͳΜ͔͸Θ͔Δ͸ͣɻҙ֎ͱ͍Ζ͍Ζݟ͔ͭΔͷͰ͸ɻ
    w Ϋϥεఆٛʹ͸ܕΛॻ͚ͳ͍ͷʁΦʔϓϯΫϥε͸Ͳ͏ͳΔͷʁ

    ࠓޙͷ՝୊ɻΦʔϓϯΫϥεͱ0CKFDUJWF$ͷ$BUFHPSZͳΜ͔
    ͸͍ۙؾ͕͢Δɻ
    w ࣮૷͸ͳ͍ͷʁ

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

    View full-size slide