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
型なし言語のための型
Search
Soutaro Matsumoto
November 03, 2019
Programming
14k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
型なし言語のための型
富山Ruby会議01
Soutaro Matsumoto
November 03, 2019
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
250
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
500
Other Decks in Programming
See All in Programming
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
golang-bob.pdf
iwatsukayura
0
110
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
360
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
140
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
240
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.5k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
190
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
8
5.6k
setup-vp GitLab対応の裏側
naokihaba
0
160
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
740
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
910
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
46
8.3k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
RailsConf 2023
tenderlove
30
1.6k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
440
It's Worth the Effort
3n
188
29k
A Tale of Four Properties
chriscoyier
163
24k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
610
The browser strikes back
jonoalderson
0
1.8k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
560
Transcript
ܕͳ͠ݴޠͷͨΊͷܕ দຊफଠ !TPVUBSP
@soutaro
@soutaro
Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯεతͰͳ͍ conf = Conference.find_by!(name: "ࢁRubyձٞ", volume:
1) conf.talks.each do |talk| puts talk.speaker.email end
Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯεతͰͳ͍ conf = Conference.find_by!(name: "ࢁRubyձٞ", volume:
1) conf.talks.each do |talk| puts talk.speaker.email end ::Conference
Ruby3ͷܕݕࠪ • RubyϓϩάϥϜͷࣜͷܕΛ࣮ߦͤͣʹఆ͠ɺ։ൃͷମݧΛվળ͢Δ • ύϑΥʔϚϯεతͰͳ͍ conf = Conference.find_by!(name: "ࢁRubyձٞ", volume:
1) conf.talks.each do |talk| puts talk.speaker.email end ::Conference () { (::Talk) -> void } -> self
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
૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1
ܕݕࠪ Level 2 ܕݕࠪ Type signature language
૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1
ܕݕࠪ Level 2 ܕݕࠪ Type signature language ༻ ༻
૬ؔਤ type-profiler Steep Sorbet RDL RBS (stdlib types) Level 1
ܕݕࠪ Level 2 ܕݕࠪ Type signature language ༻ ༻ Ruby3ʹಉࠝ ͖ͳͷΛΠϯετʔϧ
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
ΞτϥΠϯ w 3VCZͷ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ
ܕͳ͠ݴޠͷͨΊͷܕ w ܕ w ίϯύΠϧ࣌ʹ໌͢Δࣜͷଐੑ w ͋ΔछͷޡΓΛݕग़Ͱ͖Δʢܕݕࠪʣ w ܕͳ͠ݴޠ w
ίϯύΠϧ࣌ʹܕݕࠪ͞Εͳ͍ݴޠʢ㲈ಈతܕ͚ݴޠʣ w 3VCZͱ͔
ίʔυฤू ίϯύΠϧ ࣮ߦ ܕݕࠪ ίʔυฤू ίϯύΠϧ ࣮ߦ ܕݕࠪ
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 ܕݕࠪ͠ͳ͍߹ʹɺϓϩάϥϜͷ࣮ߦঢ়گʹΑͬ ͯɺ͕ݟ͔ͭΒͳ͍ʢ࣮ߦ࣌ʣ
ܕݕࠪͷಘࣦ w ͕ࣄલʹݕग़Ͱ͖Δ w ཏతͳݕࠪʢ࣮ߦͷύεʹґଘ͠ͳ͍ʣ w ॻ͚ΔϓϩάϥϜʹ੍ݶ͕ՃΘΔ w ࣮ࡍʹ࣮ߦ͞Εͳ͍ύεʹ͍ͭͯݕࠪ͞Εͯ͠·͏
4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU
4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU
ܕਪ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH
4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU
ܕਪ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH
4DIFNF 4.- )BTLFMM +BWB 3VCZ +BWB4DSJQU 1)1 1ZUIPO 5ZQF4DSJQU 4XJGU
ܕਪ 4PGU5ZQJOH (FOFSJDT '+ (SBEVBM5ZQJOH
.-ͷܕਪ 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 = <fun>
4PGU5ZQJOH w ܕͳ͠ͷݴޠʹܕΛ͚͍ͨ w ܕ͕͍ͭͨ෦Τϥʔ͕ݕग़Ͱ͖Δ w Θ͔Βͳ͍ͷ࣮ߦ࣌ʹݕࠪ͢Δ w ಈ͘ϓϩάϥϜͰ͖Δ͚ͩͦͷ··ܕݕࠪΛ௨͍ͨ͠ w
ܕऍઈରॻ͖ͨ͘ͳ͍
6OJPOUZQFT def f(x) if x 1 else "2" end end
6OJPOUZQFT def f(x) if x 1 else "2" end end
(bool) -> (Integer | String)
'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
4PGU5ZQJOH w 4DIFNFϓϩάϥϜͷܕ͚ʹඞཁͳͷ͕Θ͔ͬͨ w 6OJPOUZQFT 'MPXTFOTJUJWFUZQJOH w ࣮ w
.-ͷܕਪʹجͮ͘ͷ w ϑϩʔղੳ͢Δͷ
ͬͱۙతͳݴޠͰʁ w +BWB4DSJQUͱ͔3VCZͱ͔< > w ΦϒδΣΫτʹର͢Δଟ૬ੑ BLBμοΫλΠϐϯά w ʮ͋Δϝιου͕ఆٛ͞Ε͍ͯΔҙͷΫϥεʯΈ͍ͨͳܕ
def add(x, y) x + y end def add: [A, B] ({ +: (A) -> B }, A) -> B
3VCZͰࢼͨ͠ͱ͜Ζ w ͬͺΓݫ͍͠ w .-ͷܕਪͰॲཧͰ͖ͳ͍ఆ͕ٛͰͯ͘Δ "SSBZNBQ w Ϋϥεఆ໋͕ٛྩతʹมΘ͍ͬͯ͘ͷ͕ݫ͍͠ʢϝλϓϩάϥϛϯάʣ w
ͦͦյΕ͍ͯΔఆ͕ٛͨ͘͞Μ͋Δ w "SSBZTFMFDUWT0CKFDUTFMFDU w )BTIΛฦ͢IBTIΛఆٛͨ͜͠ͱ͕ͳ͍ਓ
"SSBZJTB0CKFDU w 0CKFDUʹରͯ͠ಈ͘ϓϩάϥϜ"SSBZʹରͯ͠ಈ͘ʁʁ class Object def use_select select [STDIN], [],
[] end end "".use_select # OK [1,2,3].use_select # ????
4PGU5ZQJOH͔ΒಘΒΕͨݟ w จͰޭ͍ͯ͠ΔΑ͏ʹݟ͑Δ͕࣮༻Ϩϕϧͷͷͳ͍ w ඞཁͦ͏ͳܕγεςϜͷػೳΘ͔͖ͬͯͨ w Ή͠ΖܕΛॻ͍ͨํ͕ྑ͍ͷͰʁʁ w ϓϩάϥϚͷҙਤΛܕͰදݱ͢Δ w
ҙਤͱҰக͠ͳ͍ίʔυΛݕग़͢Δ
(SBEVBM5ZQJOH w ਐతܕ͚ w ܕͳ͠ͷίʔυͱܕ͖ͭͷίʔυΛࠞͥΔ w ͩΜͩΜܕΛ͚͍ͯ͘ w ܕॻ͘
ܕͳ͠ݴޠͷͨΊͷܕ w ͦΕͳΓʹڧྗͳܕγεςϜ w 6OJPOUZQFT qPXTFOTJUJWFUZQJOH HFOFSJDT w μοΫλΠϐϯά
w ߏత෦ܕ w ΫϥεͷܧঝؔΛ͋ͱͰมߋͰ͖ΔΈ )BTLFMM 4XJGU $ w (SBEVBM5ZQJOH
ΞτϥΠϯ w 3VCZͷ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ
࠷ۙͷྲྀߦ w ܕ͖ͭͷํݴ w 5ZQF4DSJQU 5ZQFE4DIFNF w ܕऍͷαϙʔτ w 1ZUIPO
1)1
5ZQF4DSJQU w ݱࡏͰҰ൪উ͍ͬͯΔܕ͖ͭํݴ w λʔήοτݴޠ+4ʢϥϯλΠϜ+4ʣ class Drawer<ClothingType> { contents: ClothingType[]
= []; add(object: ClothingType) { this.contents.push(object); } } interface Sock { color: string } interface TShirt { size: "s" | "m" | "l" } const drawer: Drawer<Sock> = new Drawer() drawer.push({ color: "white" }) drawer.push({ size: "s" })
5ZQF4DSJQUͷ͍͢͝ͱ͜Ζ w ܕͳ͠ݴޠʹܕΛ͚Δਓྨͷເ͕ͬͨ w ΈΜͳܕΛॻ͍͍ͯΔͷ͕͍͢͝ w ߏతͳܕ͚ͩͰͳΜͱ͔ͳͬͯΔͷ͕͍͢͝ w 6OJPOUZQFTͱ͔qPXTFOTJUJWFUZQFTͱ͔MPHJDBMUZQFTͱ͔͠Εͬͱ ೖͬͯΔͷ͕͍͢͝
w ϥϯλΠϜͱͷ੍ΛΓӽ͑ͯಈ͍ͯΔͷ͕͍͢͝
ܕॻ͔ͳ͍͚ͯ͘ͳ͍ w ΑͬΆͲࣗ໌ͳͷҎ֎ॻ͘ w ϥΠϒϥϦͷܕEFpOJUFMZUZQFEʹू·͍ͬͯΔ const numbers: number[] = [1,2,3]
numbers.map<string>(x => x.toString())
jQuery.d.ts
ߏతͳܕ w ΫϥεͷܧঝؔͰͳ͘ɺϝιουͷू߹Ͱ෦ܕؔΛఆ͢Δ w ߏతͳܕ͚ͩͱ͍͏ͷ͍͠ w ͋Δ interface ForEach<A> {
forEach: (fun: (a: A) => void) => void } const x: ForEach<number> = [1,2,3]
ͨ·ͨ·ಉ͡ߏ͕͋ͬͨΒʁ w 5γϟπͱζϘϯ͕۠ผͰ͖ͳ͘ͳΔ w #SBOEFEUZQFͰରԠ͢Δ interface TShirt { size: "s"
| "m" | "l"; } interface Pants { size: "s" | "m" | "l"; }
ͨ·ͨ·ಉ͡ߏ͕͋ͬͨΒʁ 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"; }
6OJPO5ZQFT'MPXTFOTJUJWF5ZQJOH w OVMMVOEFpOFEͱ͏·͘ΕΔΑ͏ʹͳͬͨ const x: string | undefined = ...
// Object is possibly 'undefined'. x.toUpperCase() if (x) { x.toUpperCase() }
ϥϯλΠϜͷ੍ w +4ͷϥϯλΠϜʹͰ͖ͳ͍͜ͱ54ͰͰ͖ͳ͍ w ʮ͋Δ͕ΠϯλʔϑΣʔεʹద߹͍ͯ͠Δ͔ݕ͍ࠪͨ͠ʯ w Ϣʔβʔ͕ࣗͷͰݕূ͢Δ -PHJDBMUZQFT •
function isPants(object: any): object is Pants { return object.type == "pants" }
ݟ w ਓؒܕΛॻ͘ w ʢܕΛॻ͖ͨ͘ͳ͍ਓ5ZQF4DSJQUΛΘͳ͍ͷͰ؍ଌͰ͖ͳ͍ʣ w େମ+BWB4DSJQUͷίʔυʹܕ͕ͭ͘ w 6OJPOUZQFTͱ͔qPXTFOTJUJWFUZQJOHͱ͔͕ॏཁ w
ߏత෦ܕಈ͘ w ϥϯλΠϜͷ੍ݶΛΓӽ͑ΔͨΊ JTܕ
1ZUIPO 1)1 w ϝιουͷܕΛॻ͘ه๏͕ಋೖ͞Εͨ w ܕݕ࣮ࠪߦ࣌ w ϝιουݺͼग़͠ͷͱ͖ʹܕݕࠪ͢Δ w ੩తͳܕݕࠪث։ൃ͞Ε͍ͯΔ
function sum(int $a, int $b) { return $a + $b; }
ΞτϥΠϯ w 3VCZͷ w ܕͳ͠ݴޠͷͨΊͷܕ w 5ZQF4DSJQUͱ࠷ۙͷྲྀΕ w 3VCZͷͨΊͷܕ
3VCZͷͨΊͷܕ w 4PGUUZQJOHͷݟˠਪΛؤுΔͷઓతʢ!NBNFʣ w 5ZQF4DSJQUͷݟ w ਓྨܕΛॻ͘ w ͦΕͳΓʹڧྗͳܕγεςϜ͕͋Ε্ख͘Εͦ͏ w
1ZUIPO 1)1ͷݟ w ܕऍܾΊͳ͍ͱ͍͚ͳ͍ w ܕݕࠪثผπʔϧʹ͢Δ
ܕऍͷه๏ 3#4 w গͳ͘ͱϥΠϒϥϦͷܕΛॻ͘ํ๏͕ඞཁ w ܕݕࠪπʔϧ͕ͦΕͧΕʹ༻ҙ͢Δͷ͔ͳΓݫ͍͠ w ϥϯλΠϜͷݕ͕ࠪͰ͖Δ͚ͩͰͦΕͳΓʹخ͍͠Ͱʁ w ιʔείʔυʹຒΊࠐΉߏจ࠾༻͠ͳ͍
ΈࠐΈͷܕऍߏจʢෆ࠾༻ʣ 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
ͦΕͳΓʹϦονͳܕ w λϓϧɺϨίʔυ [Integer, Symbol] w Ϧςϥϧܕ 1, "hello", :world
w 6OJPOUZQFT Integer | String w 0QUJPOBMUZQFTɺ(FOFSJDTʜ Array[String]? w յΕ͍ͯΔͷJODPNQBUJCMF incompatible def select: [A] () { (Elem) -> A
μοΫλΠϐϯά w JOUFSGBDFΛఆٛͯ͠ɺཁٻ͞ΕΔϝιουͷू߹Λॻ͘ w ϝιου͕͋Δ͔ͳ͍͔Ͱݕࠪ͞ΕΔ interface _Push def <<: (String)
-> void end def foo: (_Push) -> void def foo(a) a << "hello" end foo [] foo "" foo 3 # Τϥʔ
࣮ߦ࣌ݕ͚ࠪͩͰ 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
IUUQTHJUIVCDPNTJEFSHPPEDIFDLUSFFSCT
·ͱΊ w 4PGUUZQJOHΈ͍ͨʹਪΛؤுΔͷ߹ཧతͰͳ͍ w ܕΛॻ͔ͳ͍ͷݫ͍͠ w ਓؒܕΛॻ͘ʢ͜͜ͰಘΒΕͨݟʣ w 3VCZͷͨΊͷܕ w
ΘΓͱϦονͳܕ(FOFSJDTɺ6OJPOUZQFTɺ'MPXTFOTJUJWFUZQJOH w μοΫλΠϐϯάؤுΔʢߏత෦ܕʣ
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