Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
多相型、推論、Ruby
Search
Soutaro Matsumoto
March 20, 2017
7.4k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
多相型、推論、Ruby
大江戸Ruby会議06
https://asakusarb.github.io/oedo06/
Soutaro Matsumoto
March 20, 2017
More Decks by Soutaro Matsumoto
See All by Soutaro Matsumoto
Making the RBS Parser Faster
soutaro
0
950
API for docs
soutaro
4
3.5k
Rubyの標準添付ライブラリを開発する
soutaro
2
240
Embedding it into Ruby code
soutaro
4
27k
Parsing RBS
soutaro
0
2.1k
Ruby programming with types in action
soutaro
4
1k
IDE Development with Ruby
soutaro
4
1.2k
Ruby 3の新機能としての静的型検査の開発
soutaro
4
7.9k
An Introduction to Static Typing in Ruby 3
soutaro
3
490
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Rails Girls Zürich Keynote
gr2m
96
14k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
230
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
How to make the Groovebox
asonas
2
2.3k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
45k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
380
Typedesign – Prime Four
hannesfritz
42
3.1k
How to train your dragon (web standard)
notwaldorf
97
6.7k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
Transcript
ଟ૬ܕɺ ਪɺ Ruby দຊफଠ @soutaro
None
None
ܕॻ͖ͨ͘ͳ͍
ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠
ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ
ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ typo͙Β͍࣮ߦ͠ͳͯ͘ൃݟ͍ͨ͠
ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ typo͙Β͍࣮ߦ͠ͳͯ͘ൃݟ͍ͨ͠ ܕઈରʹॻ͖ͨ͘ͳ͍
ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ typo͙Β͍࣮ߦ͠ͳͯ͘ൃݟ͍ͨ͠ ܕઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing
ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨ Ruby͕ཉ͍͠ ܕॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ typo͙Β͍࣮ߦ͠ͳͯ͘ൃݟ͍ͨ͠ ܕઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing
զʑ͕ཉ͍͠ͷ ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby
ଟ૬ܕ w ύϥϝʔλଟ૬Parametric Polymorphism w ෦ܕଟ૬Subtyping Polymorphism w ΞυϗοΫଟ૬Ad-hoc Polymorphism
จ຺ʹԠͯ͡ɺҰఆͷ੍ݶͷݩͰɺ ࣜʹ͍Ζ͍ΖͳܕΛ༩͑Δ
෦ܕଟ૬ w ෦ܕ “String is a Object” interface X {
void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList());
෦ܕଟ૬ w ෦ܕ “String is a Object” interface X {
void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); ҾͷܕString
෦ܕଟ૬ w ෦ܕ “String is a Object” interface X {
void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); ҾͷܕString ҾͷܕArrayList
໊લతɾߏత w ໊લతNominal ΫϥεఆٛͰએݴͯ͠෦ܕؔΛఆٛ w ߏతStructual ϝιουఆٛͷแؚؔͰ෦ܕؔΛఆٛʢΑΓ ॊೈʣ
ܕਪ w ʢશͳʣܕਪ w ϩʔΧϧܕਪ
ʢશͳʣܕਪ [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>
ϩʔΧϧܕਪ [Pierce, 1997] w ϩʔΧϧมͷܕॻ͔ͳͯ͘ྑ͍ ϝιουͱ͔ͷܕॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ ʢScala/Swift/C#/C++ʣ func
greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting }
ϩʔΧϧܕਪ [Pierce, 1997] w ϩʔΧϧมͷܕॻ͔ͳͯ͘ྑ͍ ϝιουͱ͔ͷܕॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ ʢScala/Swift/C#/C++ʣ func
greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕਪ͞ΕΔ
ϩʔΧϧܕਪ [Pierce, 1997] w ϩʔΧϧมͷܕॻ͔ͳͯ͘ྑ͍ ϝιουͱ͔ͷܕॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ ʢScala/Swift/C#/C++ʣ func
greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕਪ͞ΕΔ ؔͷܕॻ͘
զʑ͕ཉ͍͠ͷ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠
OCamlͳΜ͔͍ۙͷͰ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby # let f x
= print_string x#to_s;; val f : < to_s : string; .. > -> unit = <fun>
OCamlͳΜ͔͍ۙͷͰ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby # let f x
= print_string x#to_s;; val f : < to_s : string; .. > -> unit = <fun> #Ͱϝιουݺͼग़͠
OCamlͳΜ͔͍ۙͷͰ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby # let f x
= print_string x#to_s;; val f : < to_s : string; .. > -> unit = <fun> to_sͱ͍͏ϝιου͕͋ΕͳΜͰ͍͍ #Ͱϝιουݺͼग़͠
OCamlͰμϝͳͱ͜Ζ w OCamlΦϒδΣΫτͷपΓͰܕΛॻ͘ඞཁ͕ ͋Δ w OCamlͰॻ͚ͳ͍ϝιου w Array#map String#split
զʑ͕ཉ͍͠ͷ w ·ʔແཧ ͳʹ͔ΛఘΊͳ͍ͱ͍͚ͳ͍ɻ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby
զʑ͕ཉ͍͠ͷ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby
զʑ͕ཉ͍͠ͷ RubyͷػೳΛ੍ݶ͍ͯͬͯ͠ɺܕਪͰ͖ ΔΑ͏ʹͳΒͳ͍͔ʁʁ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby
eval w ແཧ w evalͷฦΓͷܕanyΈ͍ͨͳܕʹͯ͠͠·͑ ͍͍ͷͰʢGradual Typing [Siek and Taha,
2006]ʣ eval(gets)
ActiveRecord w DBʹଓ͠ͳ͍ͱΞτϦϏϡʔτ͕Θ͔Βͳ͍ w anyͰͳΜͱ͔͠Α͏ class Person < ApplicationRecord belongs_to
:group has_many :contacts end
ϝλϓϩάϥϛϯά define_method(:name=) do |x| @attributes[:name] = x end
ϝλϓϩάϥϛϯά class Location attr_reader :line attr_reader :column end
require w require͕࣮ߦ͞ΕΔॠؒ·ͰͲͷϓϩάϥϜ͕ಡ· ΕΔ͔Θ͔Βͳ͍ w requireϝιουͳͷͰɺ࠶ఆٛͰ͖Δ͠ɺͲ͜ ʹͰॻ͚Δ͠ɺҾʹ͕ࣜॻ͚Δ w $LOAD_PATH͋ΔΑʂ w
requireΛߏจʹͯ͠จࣈྻ͔͠ड͚औΕͳ͍ˍτο ϓϨϕϧʹ͔͠ॻ͚ͳ͍Α͏ʹ͢Εྑ͍ͷͰ
RubyGems ⚰Bundler
RubyΛ੍ݶͯ͠͏·͍͔͘ͳ͍ w ଞʹ͕͋Γɺݱ࣮తͳ੍ݶ͕ݟ͚ͭΒΕͳ͍ ʢࠓޙɺݟ͔ͭΔ͔͠Εͳ͍ʣ w ܕΛॻ͔ͳ͍લఏͰɺҰճanyʹࣦΘΕͨܕใ ΛऔΓ͢ํ๏͕ͳ͍
զʑ͕ཉ͍͠ͷ ύϥϝʔλଟ૬ ߏతͳ෦ܕଟ૬ શͳܕਪ Ruby
͝ఏҊ w ߏతͳ෦ܕଟ૬ ϩʔΧϧܕਪ Gradual Typing w ʢΘΓͱʣDuck TypingͰ͖ΔͷͰخ͍͠ w
ॻ͔ͳͯ͘ྑ͍ܕॻ͔ͳ͍ w ܕ͕ॻ͍ͯͳ͍ͱ͖ࠓͷRubyͱಉ͡ w ܕͷͨΊͷݴޠRubyͱผ requireͱ͔ΦʔϓϯΫϥεͱ͔ϝλϓϩάϥϛϯάͱ ͔ߟ͑ͳ͍ɻ
͍͍ͩͨTypeScript
# 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| … }
# 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| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
# 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| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
# 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| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕऍ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
# 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| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕऍ ӈลͷܕ͕Θ͔ΔͷͰɺܕऍෆཁ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
# 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͕ͳ͍͜ͱ͕Θ͔Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ
ܕऍ͕ͳ͚Ε͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =
person.email.map {|x| … }
ܕऍ͕ͳ͚Ε͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =
person.email.map {|x| … } ܕऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿݕࠪ͠ͳ͍
ܕऍ͕ͳ͚Ε͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped =
person.email.map {|x| … } map͕ແ͍͜ͱ࣮ߦ࣌ʹൃ֮ ܕऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿݕࠪ͠ͳ͍
# 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| … }
– RubyͷMatz lܕઈରॻ͖ͨ͘ͳ͍z
w Group.create!ͷܕ͕GroupʹͳΔͷΘ͔Βͳ͍ͷʁ Groupͷܕ͕Θ͔ΔͱࢥͬͯΔͷʁʁ w ܕΛҰͭॻ͍͍ͯͳ͍ͱͳʹΘ͔Βͳ͍ͷʁʁ ϦςϥϧͳΜ͔Θ͔Δͣɻҙ֎ͱ͍Ζ͍Ζݟ͔ͭΔͷͰɻ w ΫϥεఆٛʹܕΛॻ͚ͳ͍ͷʁΦʔϓϯΫϥεͲ͏ͳΔͷʁ ࠓޙͷ՝ɻΦʔϓϯΫϥεͱ0CKFDUJWF$ͷ$BUFHPSZͳΜ͔ ͍ۙؾ͕͢Δɻ
w ࣮ͳ͍ͷʁ Α͘ݟΔͱɺʢܕऍΛίϝϯτͱ͔Ͱॻ͘͜ͱʹ͢Εʣ͙͢ ʹ࣮Ͱ͖Δͳ͜Εʜʜ