Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
多相型、推論、Ruby
Search
Soutaro Matsumoto
March 20, 2017
7.5k
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
1.1k
API for docs
soutaro
4
3.8k
Rubyの標準添付ライブラリを開発する
soutaro
2
260
Embedding it into Ruby code
soutaro
4
28k
Parsing RBS
soutaro
0
2.3k
Ruby programming with types in action
soutaro
4
1.1k
IDE Development with Ruby
soutaro
4
1.2k
Ruby 3の新機能としての静的型検査の開発
soutaro
4
8k
An Introduction to Static Typing in Ruby 3
soutaro
3
510
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
580
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
740
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
340
Technical Leadership for Architectural Decision Making
baasie
3
630
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
450
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
620
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
420
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
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 ࣮ͳ͍ͷʁ Α͘ݟΔͱɺʢܕऍΛίϝϯτͱ͔Ͱॻ͘͜ͱʹ͢Εʣ͙͢ ʹ࣮Ͱ͖Δͳ͜Εʜʜ