Soutaro Matsumoto
March 20, 2017
6.5k

多相型、推論、Ruby

March 20, 2017

Transcript

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

2. ܕ͸ॻ͖ͨ͘ͳ͍

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

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

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

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

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

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

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

10. ଟ૬ܕ
w ύϥϝʔλଟ૬Parametric Polymorphism
w ෦෼ܕଟ૬Subtyping Polymorphism
จ຺ʹԠͯ͡ɺҰఆͷ੍ݶͷݩͰɺ
ࣜʹ͍Ζ͍ΖͳܕΛ༩͑Δ

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

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

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

14. ໊લతɾߏ଄త
w ໊લతNominal
ΫϥεఆٛͰએݴͯ͠෦෼ܕؔ܎Λఆٛ
w ߏ଄తStructual
ϝιουఆٛͷแؚؔ܎Ͱ෦෼ܕؔ܎ΛఆٛʢΑΓ
ॊೈʣ

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

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 =

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

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

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

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

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

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

23. OCamlͳΜ͔͍ۙͷͰ͸
ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
׬શͳܕਪ࿦Ruby
# let f x = print_string x#to_s;;
val f : < to_s : string; .. >
-> unit =
to_sͱ͍͏ϝιου͕͋Ε͹ͳΜͰ΋͍͍
#Ͱϝιουݺͼग़͠

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

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

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

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

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

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

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

31. ϝλϓϩάϥϛϯά
class Location
end

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

33. RubyGems
⚰Bundler

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

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

36. ͝ఏҊ
w ʢΘΓͱʣDuck TypingͰ͖ΔͷͰخ͍͠
w ॻ͔ͳͯ͘ྑ͍ܕ͸ॻ͔ͳ͍
w ܕ͕ॻ͍ͯͳ͍ͱ͖͸ࠓͷRubyͱಉ͡
w ܕͷͨΊͷݴޠ͸Rubyͱผ
requireͱ͔ΦʔϓϯΫϥεͱ͔ϝλϓϩάϥϛϯάͱ
͔͸ߟ͑ͳ͍ɻ

37. ͍͍ͩͨTypeScript

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| … }

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| … }
ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ

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| … }
ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

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| … }
ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
ܕ஫ऍ
ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

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| … }
ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ
ܕ஫ऍ
ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ
ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

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͕ͳ͍͜ͱ͕Θ͔Δ
ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

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

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

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

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| … }

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

49. w Group.create!ͷܕ͕GroupʹͳΔͷ͸Θ͔Βͳ͍ͷʁ
Groupͷܕ͕Θ͔ΔͱࢥͬͯΔͷʁʁ
w ܕΛҰͭ΋ॻ͍͍ͯͳ͍ͱͳʹ΋Θ͔Βͳ͍ͷʁʁ
ϦςϥϧͳΜ͔͸Θ͔Δ͸ͣɻҙ֎ͱ͍Ζ͍Ζݟ͔ͭΔͷͰ͸ɻ
w Ϋϥεఆٛʹ͸ܕΛॻ͚ͳ͍ͷʁΦʔϓϯΫϥε͸Ͳ͏ͳΔͷʁ
ࠓޙͷ՝୊ɻΦʔϓϯΫϥεͱ0CKFDUJWF\$ͷ\$BUFHPSZͳΜ͔
͸͍ۙؾ͕͢Δɻ
w ࣮૷͸ͳ͍ͷʁ
Α͘ݟΔͱɺʢܕ஫ऍΛίϝϯτͱ͔Ͱॻ͘͜ͱʹ͢Ε͹ʣ͙͢
ʹ࣮૷Ͱ͖Δͳ͜Εʜʜ