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 3 の型解析に向けた計画
Search
Yusuke Endoh
June 10, 2019
Programming
36
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Ruby 3 の型解析に向けた計画
名古屋Ruby会議04
http://regional-gh.rubykaigi.org/nagoya04/
Yusuke Endoh
June 10, 2019
More Decks by Yusuke Endoh
See All by Yusuke Endoh
Practical TypeProf: Lessons from Analyzing Optcarrot
mame
1
3.3k
型システムを知りたい人のための型検査器作成入門
mame
15
5.4k
TRICK 2025 Results
mame
0
5.9k
Writing Ruby Scripts with TypeProf
mame
1
1.6k
An Invitation to TRICK: How to write weird Ruby programs
mame
1
1.4k
TypeProf進捗
mame
0
140
12年前の『型システム入門』翻訳の思い出話
mame
14
2.9k
Good first issues of TypeProf
mame
4
10k
Revisiting TypeProf - IDE support as a primary feature
mame
1
4k
Other Decks in Programming
See All in Programming
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
170
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
130
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
210
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
410
Security issues being discussed on Web Platforms
petamoriken
0
1.2k
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
340
海上で動くGoサーバー: goroutineとchannelでさばく航行データストリーム
atsuki_seo
0
940
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
260
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
440
スマート反転とウェブアクセシビリティ
camiha
0
210
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
360
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
120
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
Claude Code のすすめ
schroneko
67
230k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
310
Thoughts on Productivity
jonyablonski
76
5.4k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Code Review Best Practice
trishagee
74
20k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
550
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
470
Transcript
Ruby 3の型解析に向けた計画 遠藤 侑介 名古屋Ruby会議04 (2019/06/08) 1
自己紹介:遠藤侑介 (@mametter) •クックパッドで働く フルタイムRubyコミッタ • Rubyプログラムを堅牢に • テスト、Ruby 3の静的解析 •クックパッドに興味あったら
お声がけください 2
この発表では •Ruby 3の静的解析のmatz構想 •型プロファイラの紹介と進捗 を話します 3
Rubyの型と名古屋の関係 •三浦さんからmrubyでの型推定の話を聞いて Ruby 3の静的解析は回りだした •型プロファイラはmruby-meta-circularの パクリ • 細かい設計指針の違いはあとで 4
Ruby 3の静的解析のmatz構想 •目的: バグっぽいコードを指摘する • 高速化のための解析ではない(間違ってもいい) •要件: Rubyのプログラミング体験を維持する •型を書かない選択肢を残す 5
Ruby 3の静的解析の構想 1. 標準の型シグネチャフォーマット 2. 型シグネチャなし型検査器 + 型シグネチャのプロトタイプ生成器 3. 型シグネチャあり型検査器
6
1. 型シグネチャフォーマット •Rubyコードの型情報を示すもの class Array[A] include Enumerable def []: (Integer)
-> A def []=: (Integer,A) -> A def each: { (A) -> void } -> self ... end interface generics union type option type any type Proposal: ruby-signature 7
2. 型シグネチャなし型検査 •型エラーの可能性を指摘する解析器 •アプリの型シグネチャが無くても動作する • false positive は許容する def foo(s)
s.gsuub!(//, "") s + 42 end foo("foo") NoMethodError? TypeError? Proposals: • mruby-meta-circular • 型プロファイラ 8
2'. 型シグネチャプロトタイプ生成 •無注釈コードから型シグネチャを推測する •メソッドの呼び出しを追う def foo(s) s.to_s end foo("foo") foo(42)
(String | Integer) -> String ? Proposals: • mruby-meta-circular • 型プロファイラ 9
3. 型シグネチャあり型検査 •型エラーの可能性を指摘する解析器 •型シグネチャとコードの整合性を検査する • わりと普通の型検査 •ツール定義の inline annotation も
def foo(s) s.gsuub!(//, "") s + 42 end TypeError! def foo: (String) -> Integer Proposals: • Steep • Sorbet NoMethodError! 10
Ruby 3の静的解析の図 Library code type signature Sorbet Steep RDL Type
error warnings Application code mmc Type Profiler Type error warnings type signature 11
ユースケースに合わせた使い方 •緩く検査したい派:型シグネチャなし型検査 •きっちり検査したい派: • コーディング→型シグネチャプロトタイプ→ 型シグネチャあり型検査 •型ドリブン開発派: • 型シグネチャ手書き→コーディング→ 型シグネチャあり型検査
12
Ruby 3の静的解析の進捗 •ruby-signature: ツール開発者間で議論中 •https://github.com/ruby/ruby-signature •Type-Profiler: 試験実装状態 •mruby-meta-circular: (次の発表で) •Steep:
Siderで試用中、型注釈が結構必要 •Sorbet: Stripeで試用中、duck typingがない 13
Ruby 3には何が入る? •「型シグネチャ」はバンドルしたい •型シグネチャフォーマットのパーサ • 標準添付ライブラリの型シグネチャファイル •型シグネチャ対応版RubyGems •ツール群はバンドルの予定なし • 当面は外部ライブラリとして提供される
14
型プロファイラの 紹介と進捗 15
型プロファイラとは •目的:型レベルテストとシグネチャ推定 • 型エラーの可能性を指摘する •型シグネチャのプロトタイプを生成する •対象:型注釈のない素のRubyコード 16
型エラーの指摘 •NoMethodErrorやTypeErrorの可能性を示す def foo(n) if n < 10 n.timees {|x|
} end end foo(42) Type Profiler t.rb:3: [error] undefined method: Integer#timees Typo 17
型シグネチャ推定 •型シグネチャのプロトタイプを生成する def foo(n) n.to_s end foo(42) Type Profiler Object#foo
:: (Integer) -> String 18
型プロファイラの動作イメージ •Rubyコードを「型レベル」で実行する 普通のインタプリタ def foo(n) n.to_s end foo(42) Calls w/
42 Returns "42" 型プロファイラ def foo(n) n.to_s end foo(42) Calls w/ Integer Returns String Object#foo :: (Integer) -> String 19
デモ:オーバーロードの例 def my_to_s(x) x.to_s end my_to_s(42) my_to_s("STR") my_to_s(:sym) Type Profiler
Object#my_to_s :: (Integer) -> String Object#my_to_s :: (String) -> String Object#my_to_s :: (Symbol) -> String 20
デモ:再帰関数の例 def fib(n) if n > 1 fib(n-1) + fib(n-2)
else n end end fib(10000) Type Profiler Object#fib :: (Integer) -> Integer 21
デモ:ユーザ定義クラスの例 class Foo end class Bar def make_foo Foo.new end
end Bar.new.make_foo Type Profiler Bar#make_foo :: () -> Foo 22
型プロファイラと分岐 •実行を「フォーク」する def foo(n) if n < 10 n else
"error" end end foo(42) Fork! イマココ n<10 の真偽は わからない Returns Integer Returns String Object#foo :: (Integer) -> (Integer | String) 23
最大の問題:状態爆発 •RubyKaigi時点(4月)の実験結果 •型プロファイラの型プロファイル:約10分 • optcarrotの型プロファイル:約3分 a=b=c=d=e=nil a = 42 if
n < 10 b = 42 if n < 10 c = 42 if n < 10 d = 42 if n < 10 e = 42 if n < 10 Fork! Fork! Fork! Fork! Fork! 2 4 8 16 32 状態数 24
RubyKaigi からの進捗 (1) •解析方式を大きく変えた(後述) •state merging 風の改良を加えた •改善後の実験結果 • セルフ型プロファイル:約10分
➔ 約2.5秒 • optcarrotの型プロファイル:約3分 ➔ 約6秒 25
解析にかかる時間 0 200 400 600 800 self-profiling optcarrot seconds old
new 26
RubyKaigi からの進捗 (2) •Flow sensitiveな解析 •右の例で警告が出ない • 分岐で単純フォークすると 誤警告が出てしまう def
foo(x) if x.is_a?(Integer) x + 42 else x + "str" end end foo(42) foo("str") 27
解析アルゴリズム •環境:各変数がとりうる型 •{ x: Integer or String, y: Integer }
とか •行ごとの「環境」を更新していく • 正確に言うとYARVのバイトコードごと •「環境」が更新されなくなったら終わり 28
解析の例 1: def foo(a) 2: if a < 10 3:
b = 42 4: else 5: b = "str" 6: end 7: c = b 8: c 9: end 10: 11: ret = foo(42) 行番号 a b c 1 ∅ ∅ ∅ 2 ∅ ∅ ∅ 3 ∅ ∅ ∅ 4 - - - 5 ∅ ∅ ∅ 6 - 7 ∅ ∅ ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 ∅ ∅ ∅ 3 ∅ ∅ ∅ 4 - - - 5 ∅ ∅ ∅ 6 - 7 ∅ ∅ ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 ∅ ∅ ∅ 4 - - - 5 ∅ ∅ ∅ 6 - 7 ∅ ∅ ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 ∅ ∅ ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 { Int } { Int } ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 { Int } { Int } ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 { Int } { Int, Str } ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 { Int } { Int, Str } ∅ 8 ∅ ∅ ∅ 行番号 a b c 1 { Int } ∅ ∅ 2 { Int } ∅ ∅ 3 { Int } ∅ ∅ 4 - - - 5 { Int } ∅ ∅ 6 - 7 { Int } { Int, Str } ∅ 8 { Int } { Int, Str } { Int, Str } Object#foo :: (Int) -> (Int|Str) 29
他の問題 •嘘の警告・推定が出ることがある •原理的に扱えない言語機能がある • sendメソッド・特異クラス 30 # b: Integer or
String c = b # c: Integer or String # 「bとcの型は同じ」という条件が消えるので b + c # 「Integer + String の可能性あり!」
mmcとの方針の違い •mmc: ヒューリスティクス盛りだくさん •ターゲットアプリで正しい推定をするように • mmcを更新したら推定結果が結構変わったり •型プロファイラ:理解可能な動きをすること • 解析方法を複雑化し、正しく推定するより •
解析方法を単純化し、なぜ間違えるか ユーザが理解できるようにしたい 31
実装進捗:できてること •基本的な言語機能のサポート •変数、メソッド、ユーザ定義クラスなど • 一部の組み込みクラス •ブロックと配列(たぶん) •解析アルゴリズムの基本設計 32
実装予定:やっていくこと •言語機能のサポート •ハッシュ • 複雑な引数(可変長やキーワード) •例外 • モジュール •型シグネチャ言語の読み書き •実用性向上
33
関連研究 •mruby-meta-circular (Hideki Miura) •型プロファイラの元ネタ •HPC Ruby (Koichi Nakamura) •
抽象解釈でRubyからCへ変換(HPC向け) •pytype (Google's unofficial project) • 型解析のための抽象解釈器 34
謝辞 •Hideki Miura •Matz, Akr, Ko1 •PPL paper co-authors •
Soutaro Matsumoto • Katsuhiro Ueno • Eijiro Sumii •Stripe team & Jeff Foster •And many people 35
まとめ •Ruby 3の静的解析の構想を説明しました •型プロファイラの概略を説明しました • お便りお寄せください! • https://github.com/mame/ruby-type-profiler 36