Slide 1

Slide 1 text

ܕͳ͠ݴޠͷͨΊͷܕ দຊफଠ࿠
 !TPVUBSP

Slide 2

Slide 2 text

@soutaro

Slide 3

Slide 3 text

@soutaro

Slide 4

Slide 4 text

Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹ൑ఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯε͸໨తͰ͸ͳ͍ conf = Conference.find_by!(name: "෋ࢁRubyձٞ", volume: 1) conf.talks.each do |talk| puts talk.speaker.email end

Slide 5

Slide 5 text

Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹ൑ఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯε͸໨తͰ͸ͳ͍ conf = Conference.find_by!(name: "෋ࢁRubyձٞ", volume: 1) conf.talks.each do |talk| puts talk.speaker.email end ::Conference

Slide 6

Slide 6 text

Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹ൑ఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯε͸໨తͰ͸ͳ͍ conf = Conference.find_by!(name: "෋ࢁRubyձٞ", volume: 1) conf.talks.each do |talk| puts talk.speaker.email end ::Conference () { (::Talk) -> void } -> self

Slide 7

Slide 7 text

Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹ൑ఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯε͸໨తͰ͸ͳ͍ conf = Conference.find_by!(name: "෋ࢁRubyձٞ", volume: 1) conf.talks.each do |talk| puts talk.speaker.email end ::String ::Conference () { (::Talk) -> void } -> self

Slide 8

Slide 8 text

૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1 ܕݕࠪ Level 2 ܕݕࠪ Type signature language

Slide 9

Slide 9 text

૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1 ܕݕࠪ Level 2 ܕݕࠪ Type signature language ࢖༻ ࢖༻

Slide 10

Slide 10 text

૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1 ܕݕࠪ Level 2 ܕݕࠪ Type signature language ࢖༻ ࢖༻ Ruby3ʹಉࠝ ޷͖ͳ΋ͷΛΠϯετʔϧ

Slide 11

Slide 11 text

3#4SVCZTJHOBUVSF w 3#4ΛಡΜͰɺΫϥεఆٛͷ৘ใΛॲཧ͢ΔϥΠϒϥϦ w ৄ͘͠͸དྷिͷ3VCZ)BDL$IBMMFOHF)PMJEBZͰ
 IUUQTSIDDPOOQBTTDPNFWFOU class Set[A] def initialize: (_Each[A, untyped]) -> void | () -> void def intersection: (_Each[A, untyped]) -> self ... end

Slide 12

Slide 12 text

Ξ΢τϥΠϯ w 3VCZͷ࿩ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ

Slide 13

Slide 13 text

ܕͳ͠ݴޠͷͨΊͷܕ w ܕ w ίϯύΠϧ࣌ʹ൑໌͢Δࣜͷଐੑ w ͋ΔछͷޡΓΛݕग़Ͱ͖Δʢܕݕࠪʣ w ܕͳ͠ݴޠ w ίϯύΠϧ࣌ʹܕݕࠪ͞Εͳ͍ݴޠʢ㲈ಈతܕ෇͚ݴޠʣ w 3VCZͱ͔

Slide 14

Slide 14 text

ίʔυฤू ίϯύΠϧ ࣮ߦ ܕݕࠪ ίʔυฤू ίϯύΠϧ ࣮ߦ ܕݕࠪ

Slide 15

Slide 15 text

class Person def name @name end def name=(value) @name = value end end if rand(10) < 5 person = Person.new person.nme = "Soutaro Matsumoto" # NoMethodError end w ܕݕࠪʹΑͬͯɺ໢ཏతʹʢJGͷத΋ʣݕࠪ͞Εͯɺ࣮ ߦલʹ໰୊͕ݕग़͞ΕΔʢίϯύΠϧ࣌ʣ w ܕݕࠪ͠ͳ͍৔߹ʹ͸ɺϓϩάϥϜͷ࣮ߦঢ়گʹΑͬ ͯ͸ɺ໰୊͕ݟ͔ͭΒͳ͍ʢ࣮ߦ࣌ʣ

Slide 16

Slide 16 text

ܕݕࠪͷಘࣦ w ໰୊͕ࣄલʹݕग़Ͱ͖Δ w ໢ཏతͳݕࠪʢ࣮ߦͷύεʹґଘ͠ͳ͍ʣ w ॻ͚ΔϓϩάϥϜʹ੍ݶ͕ՃΘΔ w ࣮ࡍʹ͸࣮ߦ͞Εͳ͍ύεʹ͍ͭͯ΋ݕࠪ͞Εͯ͠·͏

Slide 17

Slide 17 text

4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU

Slide 18

Slide 18 text

4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU ܕਪ࿦ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH

Slide 19

Slide 19 text

4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU ܕਪ࿦ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH

Slide 20

Slide 20 text

4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU ܕਪ࿦ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH

Slide 21

Slide 21 text

.-ͷܕਪ࿦ w ʮ࠙੾ஸೡʹશ෦ͷࣜʹܕΛॻ͔ͳͯ͘΋ྑ͍ʯͱ͍͏ൃݟ w ύϥϝʔλଟ૬ʢେମ(FOFSJDTͷ͜ͱʣ # let rec map f xs = match xs with [] -> [] | x::xs -> f x :: map f xs;; val map : ('a -> 'b) -> 'a list -> 'b list =

Slide 22

Slide 22 text

4PGU5ZQJOH w ܕͳ͠ͷݴޠʹ΋ܕΛ෇͚͍ͨ w ܕ͕͍ͭͨ෦෼͸Τϥʔ͕ݕग़Ͱ͖Δ w Θ͔Βͳ͍΋ͷ͸࣮ߦ࣌ʹݕࠪ͢Δ w ಈ͘ϓϩάϥϜ͸Ͱ͖Δ͚ͩͦͷ··ܕݕࠪΛ௨͍ͨ͠ w ܕ஫ऍ͸ઈରॻ͖ͨ͘ͳ͍

Slide 23

Slide 23 text

6OJPOUZQFT def f(x) if x 1 else "2" end end

Slide 24

Slide 24 text

6OJPOUZQFT def f(x) if x 1 else "2" end end (bool) -> (Integer | String)

Slide 25

Slide 25 text

'MPXTFOTJUJWF5ZQJOH def g(n) n.abs # NoMethodError n.bytes # n: Integer | String case n when Integer n.abs # n: Integer when String n.bytes # n: String end end (Integer | String) -> Integer

Slide 26

Slide 26 text

4PGU5ZQJOH w 4DIFNFϓϩάϥϜͷܕ෇͚ʹඞཁͳ΋ͷ͕Θ͔ͬͨ w 6OJPOUZQFT 'MPXTFOTJUJWFUZQJOH  w ࣮૷ w .-ͷܕਪ࿦ʹجͮ͘΋ͷ w ϑϩʔղੳ͢Δ΋ͷ

Slide 27

Slide 27 text

΋ͬͱۙ୅తͳݴޠͰ͸ʁ w +BWB4DSJQUͱ͔3VCZͱ͔< > w ΦϒδΣΫτʹର͢Δଟ૬ੑ BLBμοΫλΠϐϯά  w ʮ͋Δϝιου͕ఆٛ͞Ε͍ͯΔ೚ҙͷΫϥεʯΈ͍ͨͳܕ def add(x, y) x + y end def add: [A, B] ({ +: (A) -> B }, A) -> B

Slide 28

Slide 28 text

3VCZͰࢼͨ͠ͱ͜Ζ w ΍ͬͺΓݫ͍͠ w .-ͷܕਪ࿦Ͱ͸ॲཧͰ͖ͳ͍ఆ͕ٛͰͯ͘Δ "SSBZNBQ  w Ϋϥεఆ໋͕ٛྩతʹมΘ͍ͬͯ͘ͷ͕ݫ͍͠ʢϝλϓϩάϥϛϯάʣ w ͦ΋ͦ΋յΕ͍ͯΔఆ͕ٛͨ͘͞Μ͋Δ w "SSBZTFMFDUWT0CKFDUTFMFDU w )BTIΛฦ͢IBTIΛఆٛͨ͜͠ͱ͕ͳ͍ਓ

Slide 29

Slide 29 text

"SSBZJTB0CKFDU w 0CKFDUʹରͯ͠ಈ͘ϓϩάϥϜ͸"SSBZʹରͯ͠΋ಈ͘ʁʁ class Object def use_select select [STDIN], [], [] end end "".use_select # OK [1,2,3].use_select # ????

Slide 30

Slide 30 text

4PGU5ZQJOH͔ΒಘΒΕͨ஌ݟ w ࿦จͰ͸੒ޭ͍ͯ͠ΔΑ͏ʹݟ͑Δ͕࣮༻Ϩϕϧͷ΋ͷ͸ͳ͍ w ඞཁͦ͏ͳܕγεςϜͷػೳ͸Θ͔͖ͬͯͨ w Ή͠ΖܕΛॻ͍ͨํ͕ྑ͍ͷͰ͸ʁʁ w ϓϩάϥϚͷҙਤΛܕͰදݱ͢Δ w ҙਤͱҰக͠ͳ͍ίʔυΛݕग़͢Δ

Slide 31

Slide 31 text

(SBEVBM5ZQJOH w ઴ਐతܕ෇͚ w ܕͳ͠ͷίʔυͱܕ͖ͭͷίʔυΛࠞͥΔ w ͩΜͩΜܕΛ෇͚͍ͯ͘ w ܕ͸ॻ͘

Slide 32

Slide 32 text

ܕͳ͠ݴޠͷͨΊͷܕ w ͦΕͳΓʹڧྗͳܕγεςϜ w 6OJPOUZQFT qPXTFOTJUJWFUZQJOH HFOFSJDT  w μοΫλΠϐϯά w ߏ଄త෦෼ܕ w Ϋϥεͷܧঝؔ܎Λ͋ͱͰมߋͰ͖Δ࢓૊Έ )BTLFMM 4XJGU $  w (SBEVBM5ZQJOH

Slide 33

Slide 33 text

Ξ΢τϥΠϯ w 3VCZͷ࿩ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ

Slide 34

Slide 34 text

࠷ۙͷྲྀߦ w ܕ͖ͭͷํݴ w 5ZQF4DSJQU 5ZQFE4DIFNF w ܕ஫ऍͷαϙʔτ w 1ZUIPO 1)1

Slide 35

Slide 35 text

5ZQF4DSJQU w ೥ݱࡏͰҰ൪উ͍ͬͯΔܕ͖ͭํݴ w λʔήοτݴޠ͸+4ʢϥϯλΠϜ΋+4ʣ class Drawer { contents: ClothingType[] = []; add(object: ClothingType) { this.contents.push(object); } } interface Sock { color: string } interface TShirt { size: "s" | "m" | "l" } const drawer: Drawer = new Drawer() drawer.push({ color: "white" }) drawer.push({ size: "s" })

Slide 36

Slide 36 text

5ZQF4DSJQUͷ͍͢͝ͱ͜Ζ w ܕͳ͠ݴޠʹܕΛ෇͚Δਓྨͷເ͕׎ͬͨ w ΈΜͳܕΛॻ͍͍ͯΔͷ͕͍͢͝ w ߏ଄తͳܕ͚ͩͰͳΜͱ͔ͳͬͯΔͷ͕͍͢͝ w 6OJPOUZQFTͱ͔qPXTFOTJUJWFUZQFTͱ͔MPHJDBMUZQFTͱ͔͠Εͬͱ ೖͬͯΔͷ͕͍͢͝ w ϥϯλΠϜͱͷ੍໿Λ৐Γӽ͑ͯಈ͍ͯΔͷ͕͍͢͝

Slide 37

Slide 37 text

ܕ͸ॻ͔ͳͯ͘͸͍͚ͳ͍ w ΑͬΆͲࣗ໌ͳ΋ͷҎ֎͸ॻ͘ w ϥΠϒϥϦͷܕ͸EFpOJUFMZUZQFEʹू·͍ͬͯΔ const numbers: number[] = [1,2,3] numbers.map(x => x.toString())

Slide 38

Slide 38 text

jQuery.d.ts

Slide 39

Slide 39 text

ߏ଄తͳܕ w Ϋϥεͷܧঝؔ܎Ͱ͸ͳ͘ɺϝιουͷू߹Ͱ෦෼ܕؔ܎Λ൑ఆ͢Δ w ߏ଄తͳܕ͚ͩͱ͍͏ͷ͸௝͍͠ w ໰୊͸͋Δ interface ForEach { forEach: (fun: (a: A) => void) => void } const x: ForEach = [1,2,3]

Slide 40

Slide 40 text

ͨ·ͨ·ಉ͡ߏ଄͕͋ͬͨΒʁ w 5γϟπͱζϘϯ͕۠ผͰ͖ͳ͘ͳΔ w #SBOEFEUZQFͰରԠ͢Δ interface TShirt { size: "s" | "m" | "l"; } interface Pants { size: "s" | "m" | "l"; }

Slide 41

Slide 41 text

ͨ·ͨ·ಉ͡ߏ଄͕͋ͬͨΒʁ w 5γϟπͱζϘϯ͕۠ผͰ͖ͳ͘ͳΔ w #SBOEFEUZQFͰରԠ͢Δ interface TShirt { size: "s" | "m" | "l"; } interface Pants { size: "s" | "m" | "l"; } interface TShirt { type: "tshirt" size: "s" | "m" | "l"; } interface Pants { type: "pants" size: "s" | "m" | "l"; }

Slide 42

Slide 42 text

6OJPO5ZQFT'MPXTFOTJUJWF5ZQJOH w OVMMVOEFpOFEͱ͏·͘΍ΕΔΑ͏ʹͳͬͨ const x: string | undefined = ... // Object is possibly 'undefined'. x.toUpperCase() if (x) { x.toUpperCase() }

Slide 43

Slide 43 text

ϥϯλΠϜͷ੍໿ w +4ͷϥϯλΠϜʹͰ͖ͳ͍͜ͱ͸54Ͱ΋Ͱ͖ͳ͍ w ʮ͋Δ஋͕ΠϯλʔϑΣʔεʹద߹͍ͯ͠Δ͔ݕ͍ࠪͨ͠ʯ w Ϣʔβʔ͕ࣗ෼ͷ੹೚Ͱݕূ͢Δ -PHJDBMUZQFT  • function isPants(object: any): object is Pants {
 return object.type == "pants"
 }

Slide 44

Slide 44 text

஌ݟ w ਓؒ͸ܕΛॻ͘ w ʢܕΛॻ͖ͨ͘ͳ͍ਓ͸5ZQF4DSJQUΛ࢖Θͳ͍ͷͰ؍ଌͰ͖ͳ͍ʣ w େମ+BWB4DSJQUͷίʔυʹܕ͕ͭ͘ w 6OJPOUZQFTͱ͔qPXTFOTJUJWFUZQJOHͱ͔͕ॏཁ w ߏ଄త෦෼ܕ΋ಈ͘ w ϥϯλΠϜͷ੍ݶΛ৐Γӽ͑ΔͨΊ޻෉ JTܕ

Slide 45

Slide 45 text

1ZUIPO 1)1 w ϝιουͷܕΛॻ͘ه๏͕ಋೖ͞Εͨ w ܕݕࠪ͸࣮ߦ࣌ w ϝιουݺͼग़͠ͷͱ͖ʹܕݕࠪ͢Δ w ੩తͳܕݕࠪث΋։ൃ͞Ε͍ͯΔ function sum(int $a, int $b) { return $a + $b; }

Slide 46

Slide 46 text

Ξ΢τϥΠϯ w 3VCZͷ࿩ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ

Slide 47

Slide 47 text

3VCZͷͨΊͷܕ w 4PGUUZQJOHͷ஌ݟˠਪ࿦ΛؤுΔͷ͸௅ઓతʢ!NBNFʣ w 5ZQF4DSJQUͷ஌ݟ w ਓྨ͸ܕΛॻ͘ w ͦΕͳΓʹڧྗͳܕγεςϜ͕͋Ε͹্ख͘΍Εͦ͏ w 1ZUIPO 1)1ͷ஌ݟ w ܕ஫ऍ͸ܾΊͳ͍ͱ͍͚ͳ͍ w ܕݕࠪث͸ผπʔϧʹ͢Δ

Slide 48

Slide 48 text

ܕ஫ऍͷه๏ 3#4 w গͳ͘ͱ΋ϥΠϒϥϦͷܕΛॻ͘ํ๏͕ඞཁ w ܕݕࠪπʔϧ͕ͦΕͧΕʹ༻ҙ͢Δͷ͸͔ͳΓݫ͍͠ w ϥϯλΠϜͷݕ͕ࠪͰ͖Δ͚ͩͰ΋ͦΕͳΓʹخ͍͠Ͱ͸ʁ w ιʔείʔυʹຒΊࠐΉߏจ͸࠾༻͠ͳ͍

Slide 49

Slide 49 text

૊ΈࠐΈͷܕ஫ऍߏจʢෆ࠾༻ʣ class Box extend T::Sig extend T::Generic Elem = type_member sig {returns(Elem)} # @type var box: Box[Integer] box = Box.new box.x = "hello" &NCFEEFE%4- 4PSCFU $PNNFOUT 4UFFQ class Box [A] def value: A; ...; end def value=(value: A): A; ...; end end a: Box[Integer] = Box.new

Slide 50

Slide 50 text

ͦΕͳΓʹϦονͳܕ w λϓϧɺϨίʔυ
 [Integer, Symbol] w Ϧςϥϧܕ
 1, "hello", :world w 6OJPOUZQFT
 Integer | String w 0QUJPOBMUZQFTɺ(FOFSJDTʜ
 Array[String]? w յΕ͍ͯΔ΋ͷ͸JODPNQBUJCMF
 incompatible
 def select: [A] () { (Elem) -> A

Slide 51

Slide 51 text

μοΫλΠϐϯά w JOUFSGBDFΛఆٛͯ͠ɺཁٻ͞ΕΔϝιουͷू߹Λॻ͘ w ϝιου͕͋Δ͔ͳ͍͔Ͱݕࠪ͞ΕΔ interface _Push def <<: (String) -> void end def foo: (_Push) -> void def foo(a) a << "hello" end foo [] foo "" foo 3 # Τϥʔ

Slide 52

Slide 52 text

࣮ߦ࣌ݕ͚ࠪͩͰ΋ w γάωνϟΛॻ͍ͨΒɺϢχοτςετͰςετ͢Δํ๏Λఏڙ w ϝιουݺͼग़͠ͷલޙʹܕݕࠪΛૠೖ w IUUQTSIDDPOOQBTTDPNFWFOU $ RBS_TEST_TARGET='Goodcheck::*' \ RBS_TEST_RAISE=true \ RUBYOPT='-rbundler/setup -rruby/signature/test/setup' \ RBS_TEST_OPT='-rset -rpathname -Isig' \
 bundle exec rake test

Slide 53

Slide 53 text

IUUQTHJUIVCDPNTJEFSHPPEDIFDLUSFFSCT

Slide 54

Slide 54 text

·ͱΊ w 4PGUUZQJOHΈ͍ͨʹਪ࿦ΛؤுΔͷ͸߹ཧతͰ͸ͳ͍ w ܕΛॻ͔ͳ͍ͷ͸ݫ͍͠ w ਓؒ͸ܕΛॻ͘ʢ͜͜೥ͰಘΒΕͨ஌ݟʣ w 3VCZͷͨΊͷܕ w ΘΓͱϦονͳܕ(FOFSJDTɺ6OJPOUZQFTɺ'MPXTFOTJUJWFUZQJOH w μοΫλΠϐϯά͸ؤுΔʢߏ଄త෦෼ܕʣ

Slide 55

Slide 55 text

w <$BSUXSJHIU >3$BSUXSJHIUBOE.'BHBO4PGUUZQJOH w <.BUTVNPUP >4.BUTVNPUPBOE:.JOBNJEF5ZQF*OGFSFODFGPS3VCZ 1SPHSBNTCBTFEPO1PMZNPSQIJD3FDPSE5ZQFT w <+FOTFO >4)+FOTFOBOE".”MMFSBOE15IJFNBOO 5ZQF"OBMZTJTGPS +BWB4DSJQU w <4JFL >+4JFLBOE85BIB (SBEVBM5ZQJOHGPS0CKFDUT w <)PDITUBEU >45)PDITUBEU 5ZQFE4DIFNF'SPN4DSJQUTUP1SPHSBNT w