🦉

Type Ruby Concept

に公開

Money Forward Fukuoka Advent Calendar 2025 23日目です。

yiyenene と申します。

Ruby と型システム

https://x.com/yukihiro_matz/status/1841018946776154431?s=20

不穏な話をしたいわけではないですが、Ruby における静的型付けの議論は長い間行われています。私は rbs が好きですが、全く書けていません。やはり実装を書き終わった後に(あるいは書く前に)別のファイルにわざわざ定義を書くという行為をさせるにはかなり強い動機が必要になると思います。
rbs-inline はそういう意味では良いアプローチだと思っていて、同じファイル内で宣言が済む、となれば書いてあげてもいいかなと思う人もより多く出てくるでしょう。

ですがコメントを書くという行為も極端に言えば不要なはずの行為であり、手間が増えてしまっています。やはり言語として書いたものから必要な情報が抽出されるほうが自然です。そのためには言語自体に型付けの情報が含まれるようになった上で、それを活用できるほうが嬉しいですよね。

Concept

https://github.com/yiyenene/type_ruby_concept

ということで最小限ではありますがコンセプトモデルを作ってみました。
以下のような文法で書かれた trb ファイルを rbs-inline のコメントがついた rb ファイルに transplie するというコンセプトです。

class Greeter
  attr_reader name: String
  attr_reader age: Integer

  def initialize: (name: String, age: Integer) -> void
    @name = name
    @age = age
  end

  def greet: () -> String
    "Hello #{name}! I'm #{age} years old!"
  end
end

let greeter = Greeter.new(name: 'typed ruby', age: 0)
pp greeter.greet

↓ transpliled

class Greeter
  attr_reader :name #: String
  attr_reader :age #: Integer

  #: (name: String, age: Integer) -> void
  def initialize(name:, age:)
    @name = name
    @age = age
  end

  #: () -> String
  def greet
    "Hello #{name}! I'm #{age} years old!"
  end
end

greeter = Greeter.new(name: 'typed ruby', age: 0)
pp greeter.greet

ruby にそのまま引き渡して実行するとこんな感じ。

> trb run examples/hello.trb
"Hello typed ruby! I'm 0 years old!"

ruby であるために何が必要か

型付きであることが開発者体験を良くする例としてはコンパイル時の警告であったりエラーであったりだと思います。このコンセプトではこのような例を作りました。

let test = 'test'
test = 100
pp test
> trb run examples/warning.trb
Warning at line 2, column 1: Type mismatch for variable 'test'.
  Expected: String
  Found: Integer
  Variable was declared at line 1, column 1.
100

型が付いていると言ってもいろいろあって、このケースはエラーでしょ?とか let でなく const にしてそもそも再代入を禁止すべきでしょ?とかこの例だけ見てもいろんな考え方ができると思います。

ruby の現在の仕様は様々な議論を経た上で ruby であるために取られている選択だと思います。typed ruby を作るとしてそれをどれだけ尊重するか、またはしないかのバランスが一番難しいところのように思います。
個人的にはこのケースの場合はエラーではなく、警告として気づきを与えるという選択が良いのではないかと思いました。設定で選べるようにするのもいいかもしれません。
ruby らしい楽しさとか懐の広さを保ちつつ、より有用な情報を提供できてこそ意味がある、ような気がします。


いかがでしたか?こんなプログラミング言語もあっていいんじゃないでしょうか?
仕様策定を進めてもう少しいろいろ動くようになったら面白いかもと思いつつ、今のところはこの先全く未定です。

それではお先に失礼します。

Money Forward Developers

Discussion