Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Ruby 3 の型解析に向けた計画
Search
Yusuke Endoh
June 10, 2019
Programming
31
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.1k
型システムを知りたい人のための型検査器作成入門
mame
15
5.4k
TRICK 2025 Results
mame
0
5.7k
Writing Ruby Scripts with TypeProf
mame
1
1.4k
An Invitation to TRICK: How to write weird Ruby programs
mame
1
1.4k
TypeProf進捗
mame
0
120
12年前の『型システム入門』翻訳の思い出話
mame
14
2.8k
Good first issues of TypeProf
mame
4
10k
Revisiting TypeProf - IDE support as a primary feature
mame
1
3.8k
Other Decks in Programming
See All in Programming
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.4k
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
0
170
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.4k
Android CLI
fornewid
0
190
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
560
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
280
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
17k
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
340
Foundation Models frameworkで画像分析
ryodeveloper
1
160
自動化したのに回らないテスト運用の壁ーAI時代の品質責任と生産性
mfunaki
0
110
数百円から始めるRuby電子工作
tarosay
0
120
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
270
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
First, design no harm
axbom
PRO
2
1.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
230
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.1k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
520
Building Adaptive Systems
keathley
44
3.1k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
200
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
540
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
510
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
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