SlideShare a Scribd company logo
1 of 40
Download to read offline
Ruby 3の型推論やってます
遠藤 侑介
Ruby 3 さみっと
1
雑談:endless新作
• ruby masterに新文法提案して仮採択されました
• Endless method definition [Feature #16746]
• この資料でもさっそく使っていきます!
• と思ったけど、脳負荷がありそうなので控えめに
2
def foo = 42
def foo
42
end
= と同じ
Ruby 3の型を1ページで
Ruby 3は型記述言語・型推論・型検査を提供したい
3
def inc:
(Integer) -> Integer
① 型記述言語
(RBS; ruby-signature)
def inc(n) = n+1
コード
② 型推論
(ruby-type-profiler)
③ 型検査
(Steep, Sorbet, …)
この発表では
②型推論を
話します
Ruby 3の型推論を1ページで
• 型プロファイラ:型レベルのRubyインタプリタ
• メソッドが受け取った型・返した型を集めて表示する
4
def foo(n)
n.to_s
end
foo(42)
Integer
String
def foo:
(Integer) -> String
いい感じのデモ:ao.rb
• 3Dレイトレーサ
• 300行のトイプログラム
• Syoyo Fujita, Hideki Miura作
• https://code.google.com/
archive/p/aobench/
• 若干改変あり
5
Demo: ao.rb
6
class Vec
@x : Float
@y : Float
@z : Float
initialize : (Float, Float, Float) -> Float
x : () -> Float
x= : (Float) -> Float
...
vadd : (Vec) -> Vec
vsub : (Vec) -> Vec
vcross : (Vec) -> Vec
vdot : (Vec) -> Float
vlength : () -> Float
vnormalize : () -> Vec
3Dベクトルのクラス
ベクトル演算たち
座標
attr_accessor
Demo: ao.rb
7
class Scene
@spheres : [Sphere, Sphere, Sphere]
@plane : Plane
initialize : () -> Plane
ambient_occlusion : (Isect) -> Vec
render : (Integer, Integer, Integer) -> Integer
end
class Sphere
@center : Vec
@radius : Float
initialize : (Vec, Float) -> Float
intersect : (Ray, Isect) -> (NilClass | Vec)
end
3つの球
球は中心と半径
Demo: ao.rb
8
class Ray
@org : Vec
@dir : Vec
initialize : (Vec, Vec) -> Vec
org : () -> Vec
dir : () -> Vec
end
class Isect
@t : Float
@hit : FalseClass | TrueClass
@pl : Vec
@n : Vec
initialize : () -> Vec
光線は起点と方向
交点の判定・計算
交わるか否か
boolean相当
Demo: ao.rb
• いい感じでは?
9
アジェンダ
• ➔型プロファイラの設計と性質
• 目標とアプローチ
• 普通の型システムとの違い
• デモと考察
• 型プロファイラの実装や工夫
• 今後
10
型プロファイラの目標とアプローチ
• 目的:型注釈なしRubyコードを静的解析する
• 主目的:型記述(RBS)のプロトタイプを作る
• 副目的:型エラーの可能性も指摘したい
• アプローチ:抽象解釈ベースの解析
11
def foo(n)
n.to_s
end
foo(42)
Integer
String
def foo:
(Integer) -> String
普通の型システムとの違い
• 普通の型システムはメソッド単位で解析する
• 仮引数の型はどうする?
• 手書きする(TypeScript他)
• 我々の目的には合わない
• 使われ方を見て決める(ML他)
• 右のような例で難しい
12
class A
def foo = 42
end
class B
def foo = "str"
end
def f(n)
n.foo #=> 何?
end
型プロファイラの pros/cons
pros
•型注釈なしで解析可能
•型注釈なしで解析可能
•型注釈なしで解析可能
•型注釈なしで解析可能
•型注釈なしで解析可能
※ただし~(後で)
cons
•解析が遅い
•テストが必要
•誤推定はある
•解析の理解が難しい
•開発体験が未知
めちゃくちゃ挑戦的!
13
アジェンダ
• 型プロファイラの設計と性質
• ➔デモと考察
• diff-lcs
• ruby-type-profiler
• 型プロファイラの実装や工夫
• 今後
14
事例:diff-lcs
• 最長共通部分列ライブラリ
• ダウンロード数4位の人気gem→
• 簡単なテスト↓を起点に解析
15
https://bestgems.org/
require_relative "diff-lcs/lib/diff/lcs"
class T; end
Diff::LCS.diff([T.new]+[T.new], [T.new]+[T.new]) {}
diff-lcs解析結果(そこそこいい感じの例)
16
class Diff::LCS::Change
include Comparable
@element : NilClass | T | any
@position : Integer | any
@action : :+ | :- | any
self.valid_action? :
(:! | :+ | :- | :< | :== | :> | any) -> (FalseClass | TrueClass)
action : () -> (String | any)
position : () -> (Integer | any)
element : () -> (NilClass | T | any)
initialize : (String | any, Integer | any, NilClass | T | any) -> NilClass
to_a : () -> ([String | any, Integer | any, NilClass | T | any])
unchanged? : () -> (FalseClass | TrueClass | any)
end
列の中の要素
追加削除の位置
追加 or 削除 ※元コードはStringでしたがデモのためSymbolに書き換えた
誤推定っぽいのは薄くしてます
diff-lcs解析結果(難しい例)
• 引数に依存して返り値の型が変わるメソッド
• diff(ary, ary, DiffCallbacks) ➔ Array[Array[Diff::LCS::Change]]
• diff(ary, ary, SDiffCallbacks)➔ Array[Diff::LCS::ContextChange]
•オーバーロードのRBSは手書きしてください
17
module Diff::LCS
self.diff :
(Array[T] | Diff::LCS, Array[T] | any, ?NilClass)
-> (Array[Array[Diff::LCS::Change | NilClass | any] |
Diff::LCS::Change | Diff::LCS::ContextChange | NilClass | any] | any)
end
diff-lcsで出た警告の例
• flow-sensitiveな解析が必要
※実際にはもっといっぱい出てます
個別に原因究明して、修正や改善検討をする……
18
if callbacks.respond_to?(:finished_a) and …
…
callbacks.finished_a(event)
#=>「NilClass#finished_aを呼ぶかも」警告が出る
…
else
事例:type-profiler
• 型プロファイラのコード
• Rubyで書かれている(5000行くらい)ので
• 型プロファイルできる
19
type-profiler解析結果(いい感じの例)
20
class TP::Type
include TP::Utils::StructuralEquality
self.any : () -> TP::Type::Any
self.bool : () -> TP::Type::Union
self.nil : () -> TP::Type::Instance
self.optional :
(TP::Type | TP::Type::Any | TP::Type::Array | … | any) ->
(TP::Type | TP::Type::Any | TP::Type::Array | … | any)
self.guess_literal_type :
(any) ->
(TP::Type::Any | TP::Type::Array | … | TP::Type::Symbol)
…
end
type-profiler解析結果(難しい例)
• 再帰構造がfalse positiveになる例
• ExecutionPoint (EP)は外側のEPへの参照を持つ
21
class TypeProfiler::ExecutionPoint
…
@outer : NilClass | TypeProfiler::ExecutionPoint | any
# 一番外側のEPをたどるコード
ep = EP.new(…)
while ep.outer
ep = ep.outer #=>「NilClass#outerを呼ぶかも」警告が出る
end
ep.pc #=>「NilClass#pcを呼ぶかも」警告が出る
type-profilerその他問題点(抜粋)
• 巨大なUnionが出てきてつらい
• 継承関係を利用してまとめる?
• 型のエイリアスをうまく作る?
• Object#method経由の呼び出しが追えない
• 作り込みが足らない
※実際にはもっといっぱい(略)
22
(TP::Type | TP::Type::Any | TP::Type::Array | … | any)
FAQ
• X | any は any と同じでは?
• おっしゃるとおり
• でもRBSプロトタイプ生成には便利なので
あえて潰さずに残している
23
アジェンダ
• 型プロファイラの設計と性質
• デモと考察
• ➔型プロファイラの実装や工夫
• 扱う型
• 分岐、可変長引数やキーワード引数
• ダミー実行や診断機能
• 今後
24
扱う型:普通のやつ
• 普通のインスタンス
• NilClass、Integer、String、Objectなど
• ユーザ定義クラス
• 普通のクラスオブジェクト
• クラスメソッド定義などで必要
• クラスのクラスや、特異クラスは扱わない
• any型
• 未定義メソッド呼出、ダミー実行(後述)などで発生
• anyのメソッド呼び出し(any.foo())は無視する
25
扱う型:コンテナ周り
• 具体型:Symbol、リテラル型
• :key などは具体値として扱う
• 整数 42 などは同一メソッド内では具体値として扱う
• コンテナ型:配列とハッシュ
• [X, Y, *Z]: 先頭はX型、次はY型、残りはZ型の配列
• [Integer, String]: 整数と文字列のタプル(ary[0]は先頭)
• [*Integer]: 長さ不明の整数シーケンス
• (RBSより表現力が少し強いので、RBSにするとき情報が落ちる)
• {X=>Y, Z=>W}: キーがX型なら値はY型…、なハッシュ
• {:key1=>Integer, Symbol=>String}
26
扱う型:その他
• Proc型: ブロック、具体値として扱う
• callやyieldをなるべく正確にトレースするため
• Union型: 型の和集合の型
• (Integer | String) : 整数か文字列
• 工夫(というか制限)
• ([*Integer] | [*String])は[*(Integer|String)]に潰す
• 不正確だけど、組合せ爆発を避けて解析高速化を選んだ
27
分岐の扱い
• 両方実行して、Union型で合流する
※解析を確実に合流させるのは意外と難しく、ヒューリスティクスを使ってる(PCが小さい方から解析する)
28
x = nil
if rand < 0.5
x = 42
else
x = "str"
end
p(x) #=> Integer|String
可変長引数とキーワード引数
• なんかそれっぽく動く(実装は地味に大変だった)
29
def foo(a, *r, z)
r
end
foo(1, 2, 3)
foo(1, 2, "S", 3)
def foo:
(Int, *Int|Str, Int)
-> Array[Int|Str]
def foo(n:, s:)
{ N: n, S: s }
end
foo(n: 42, s: "str")
def foo:
(n: Int, s: Str)
-> {:N=>Int, :S=>Str}
「ダミー実行」(1)
• 解析が到達できないメソッドは解析できない
• ダミー実行:未到達メソッドを無理やり実行する
• 引数はすべてanyとする
30
def foo(n)
n
end
def bar(a, b, c)
foo(42)
end
fooもbarも
テストがない
ここにfooのヒントが
あるけど使えない
「ダミー実行」(2)
• ダミー実行は良し悪し
• ゴミ情報が波及することも
31
# ao.rb抜粋
class Vec
# このメソッドは使われない
def vadd(b) # b: any
Vec.new(
@x + b.x, # any
@y + b.y, # any
@z + b.z, # any
)
end
end
class Vec
@x: Float | any
@y: Float | any
@z: Float | any
# 今はチートコードを追加(広義の型注釈?)
if _ = false
v = Vec.new(0.0,0.0,0.0)
v.vadd(v)
end
vaddをanyで呼び出すので
@xにanyが記録される
記録されない特殊な
anyで解決できる?
解析の診断機能
• pで型をrevealできる
• 「ここにどんな型が来ると思ってる?」とか調べる
• 解析到達経路をバックトレース風に表示する機能
32
def foo(n)
p n
end
foo(1)
foo("str")
# Revealed types
# reveal.rb:2 #=> Integer | String
# Classes
class Object
foo : (Integer | String) -> (Integer | String)
end
困難に対して
• 解析が遅い ➔ (精度を犠牲にしつつ)高速化してきた
• テストが必要 ➔ (荒削りだけど)ダミー実行
• 誤推定・誤検出 ➔ (限界はあるけど)改善中
• 解析の理解が難しい ➔ (簡単だけど)診断機能
• 開発体験が未知 ➔ ?
33
アジェンダ
• 型プロファイラの設計と性質
• デモと考察
• 型プロファイラの実装や工夫
• ➔今後
• 型プロファイラによるプログラミング体験
• 開発進捗と今後の予定
34
polyglot
• 2つの言語で解釈可能なプログラム
• 例:RubyとJavaScriptのpolyglot
• コツ:片方の言語だけで解釈されるように頭を使う
35
if (0)
print("Hello Ruby") [ここはRuby]
else
console.log("Hello JS") [ここはJS]
// end
型はpolyglot
• 型付き言語のプログラムはpolyglot
• インタプリタが動的な意味で解釈できる
• さらに、型システムが静的な意味で解釈できる
• 型注釈はチート(polyglotの観点では)
• 型システムだけに指示を与えられるずるい記述
36
型プロファイラの開発体験?
• ずるくないpolyglot
• 普通の実行に加え、型レベル実行を意識して書く
• 別言語ではないのでそこまでつらくないと思う
• それでもメリットはある(はず)
• 型注釈なしの記述は疑いなくシンプル
• 型プロファイラが解析できる≒素直な良いコード?
37
def foo(n: Integer | String) : Integer | String
p n
end
foo(1)
foo("str")
def foo(n)
p n
end
foo(1)
foo("str")
vs.
進捗と今後
• 現状:やっとスタート地点
• 解析器の基本設計ができた
• Rubyのおおよその言語機能がサポートできてきた
• 組み込みクラスの知識をRBSから取り込んだ
• 今後:実験と改善を繰り返す
• バグの洗い出しと修正
• プログラミング体験の設計と不足機能の実装
• 診断機能、差分更新機能
• Railsアプリ解析用のドライバ開発
• など
38
まとめ
• Ruby 3は型記述言語・型推論・型検査を提供し
たい
• 型推論担当の型プロファイラをやってます
• (寛容な心で)手伝ってくれる人たのむ!
• https://github.com/mame/ruby-type-profiler
• ruby-jp slack の #types でも
39
説明しなかったこと
• オーバーロードの推定は諦めた
• 爆発する
• オーバーロードするときは基本的に手書きして
• 再帰呼び出しはいい感じにできる
• でも再帰的なデータ構造のハンドリングは微妙
• カスタムメソッド
• 型プロファイラプラグイン
• インスタンス変数の配列の破壊
• を説明するには、まずコンテナ型がメソッドを跨がらな
いことを説明しないと……
40

More Related Content

What's hot

What's hot (20)

Docker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよDocker composeで開発環境をメンバに配布せよ
Docker composeで開発環境をメンバに配布せよ
 
Docker超入門
Docker超入門Docker超入門
Docker超入門
 
SQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルSQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイル
 
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
 
『コンテナ疲れ』と戦う、k8s・PaaS・Serverlessの活用法
『コンテナ疲れ』と戦う、k8s・PaaS・Serverlessの活用法『コンテナ疲れ』と戦う、k8s・PaaS・Serverlessの活用法
『コンテナ疲れ』と戦う、k8s・PaaS・Serverlessの活用法
 
Ruby でつくる型付き Ruby
Ruby でつくる型付き RubyRuby でつくる型付き Ruby
Ruby でつくる型付き Ruby
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Machine learning CI/CD with OSS
Machine learning CI/CD with OSSMachine learning CI/CD with OSS
Machine learning CI/CD with OSS
 
CI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKan
CI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKanCI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKan
CI/CDって何が良いの?〜言うてるオレもわからんわ〜 #DevKan
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
 
Cognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しようCognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しよう
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
 
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理
 

Similar to Ruby 3の型推論やってます

12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
Haruka Ozaki
 
リテラル文字列型までの道
リテラル文字列型までの道リテラル文字列型までの道
リテラル文字列型までの道
Satoshi Sato
 
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
Nozomu Kaneko
 
Ruby講座第二回
Ruby講座第二回Ruby講座第二回
Ruby講座第二回
mitsunaga
 
2011年11月11日
2011年11月11日2011年11月11日
2011年11月11日
nukaemon
 

Similar to Ruby 3の型推論やってます (20)

How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
すごいHaskell読書会 第7章 (前編)
すごいHaskell読書会 第7章 (前編)すごいHaskell読書会 第7章 (前編)
すごいHaskell読書会 第7章 (前編)
 
Pythonintro
PythonintroPythonintro
Pythonintro
 
Python勉強会2-数値と文字列
Python勉強会2-数値と文字列Python勉強会2-数値と文字列
Python勉強会2-数値と文字列
 
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
リテラル文字列型までの道
リテラル文字列型までの道リテラル文字列型までの道
リテラル文字列型までの道
 
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
 
数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ
 
超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみる超初心者がローマ数字をいろいろパースしてみる
超初心者がローマ数字をいろいろパースしてみる
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
 
 
  
 
 
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで)純LISPのようなナニかを作る(Lambdaだけで)純LISPのようなナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
 
Ruby講座第二回
Ruby講座第二回Ruby講座第二回
Ruby講座第二回
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
2011年11月11日
2011年11月11日2011年11月11日
2011年11月11日
 
Ruby4章
Ruby4章Ruby4章
Ruby4章
 
Ruby4章
Ruby4章Ruby4章
Ruby4章
 
Python勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイルPython勉強会3-コレクションとファイル
Python勉強会3-コレクションとファイル
 

More from mametter

クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
mametter
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProf
mametter
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
mametter
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpreter
mametter
 

More from mametter (20)

error_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticserror_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnostics
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
 
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProf
 
TypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without AnnotationsTypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without Annotations
 
Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画
 
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRubyemruby: ブラウザで動くRuby
emruby: ブラウザで動くRuby
 
Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3
 
マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
 
A Plan towards Ruby 3 Types
A Plan towards Ruby 3 TypesA Plan towards Ruby 3 Types
A Plan towards Ruby 3 Types
 
Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画
 
A Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and UnderstandingA Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and Understanding
 
本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能
 
Transcendental Programming in Ruby
Transcendental Programming in RubyTranscendental Programming in Ruby
Transcendental Programming in Ruby
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpreter
 
Ruby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるRuby 3のキーワード引数について考える
Ruby 3のキーワード引数について考える
 
TRICK 2018 results
TRICK 2018 resultsTRICK 2018 results
TRICK 2018 results
 
Type Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesType Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signatures
 
Esoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in RubyEsoteric, Obfuscated, Artistic Programming in Ruby
Esoteric, Obfuscated, Artistic Programming in Ruby
 

Ruby 3の型推論やってます