yhara.jp

Recent Posts

処理系Slackのミートアップに参加しました

2021-05-29
Tech

処理系Slackで定期ミートアップをやろうという話になったので、せっかくだからShiikaについて相談したいことを話してみた。以下は発表資料。

Shiikaとは

  • 雑に書ける静的型付け言語がほしい
  • 既存の静的言語は「性能」とか「ローレベル」にチューニングされているが、それらを捨ててLL的な方向に振る
  • Ruby的な書きやすさ+静的型チェック
  • 動的言語の楽しさとは別に、型からデザインする楽しさというのがある

最近やったこと

  • 定数の相対参照を実装した

Shiikaの定数の特殊な点

  • Rubyの「クラスもオブジェクト」をやりたい
p String  #=> #<class String>
p String.name  #=> "String"
p String.class  #=> #<class Meta:String>
  • ジェネリクスの場合はこうなってほしい
p Array  #=> #<class Array>
p Array<Int> #=> #<class Array<Int>>
  • 今までこれは Array<Int> という名前の定数と考えていた
  • しかしメソッド内では型パラメータが直接出現し得る
class Array<T>
  def example
    ret = Array<T>.new
    p Array<T>  #=> ???
  end
end

Array<Int>.new.example    #=> #<class Array<Int>>
Array<String>.new.example #=> #<class Array<String>>
  • 今は Array<T> という定数があることにしているが明らかに不自然
  • <>は演算子であるという方向で再整理する

今やっていること

  • enumを入れたい
    • Option型とResult型がほしいので
enum Maybe<T>
  case Some<T>(value: T)
  case None
end
  • これにより、以下のクラスが定義される
    • class Maybe<T>
    • class Maybe::Some<T> : Maybe<T> # !?
    • class Maybe::None : Maybe<T>
  • …というところで、まだスーパークラスに型パラメータを書けるようにしてないことに気づいた

ジェネリクスとスーパークラス

  • class Foo : String
  • class Foo : Array<Int>
  • class Foo : Array<T> # これはだめ
  • class Foo : Array # これもだめ
  • class Foo<T> : Array<T> # これはOK

ここまではいいとして、以下のような例がある

  • class Foo<S, T> : Pair<S, T>
  • class Foo<S, T> : Pair<T, S> # 順序に意味がある(クラス名だけ覚えるのではだめ)
    • class Foo<Int, Bool> の親は class Pair<Bool, Int>
    • class Foo<String, Float> の親は class Pair<Float, String>
  • class Foo<S, T> : Pair<T, Array<S>> # こんな例も

だとしたら:の右辺に書けるのは何なんだろうか?

  • Pair<T, S>というクラス」があるわけではない
  • ベースクラスとスーパークラスの対応関係を表している

その他雑談(時間があれば)

  • panicとResultはどう使い分ける?
    • 「処理系のバグならpanic」で
  • Rustのモジュール分けこれでいいのかわからん
  • 進捗書く場所の使い分け

発表を終えて

いろいろご意見をいただいたが、特にenumについて一つクリティカルな指摘があった。

enum Either<S, T>
  case Left<S>(value: S)
  case Right<T>(value: T)
end

としたとき、class Left<S> : Either<S, T>となるのではTが未定義になって困るよね、という話。

Scalaを参考にすると、ここはclass Left<S, T> : Either<S, T>が正しいっぽい。ソーステキスト上はSだけ書けばいいけど、型としてはLeftもTを持っていると。

これで気づいたんだけど、発表資料のclass Maybe::None : Maybe<T>が既におかしかったな(Tが未定義)。これも、Scalaを参考に class Maybe::None : Maybe<Never>が正しい(Neverはbottom型)。

どうしても静的型言語の実用経験が浅いので、このへんをチェックしてもらえるのはとてもありがたい。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author