処理系ミートアップ #4
2021-07-10
Event最近やったこと
- 『定理証明支援系 Coq チュートリアル』に参加した - yhara.jp
- BiwaScheme/バグ修正
- Shiika/型名の名前解決を実装
- impl. type name lookup in signatures and superclass by yhara · Pull Request #291 · shiika-lang/shiika
- 相対パスで書けるようになった
- 存在しない名前を書いたとき、きちんとエラーが出るようになった
Shiika/型名、定数名、クラス名
- メソッドの引数に
s: String
と書いたとき、String
は型名 String.new
と書いたとき、String
はクラス名- また、定数
::String
の参照でもある
一般に
- クラスAを定義したとき、
-「型A」は「Aのインスタンスであるオブジェクト」を表す。
- 定数
::A
が定義され、その値はAのクラスオブジェクトで、その型はMeta:A
- 定数
- メタクラス
- クラスオブジェクトのクラス
- クラスごとに別の型になる(
A.new
とB.new
は引数が違うかもしれないので同じにはできない) a : A : Meta:A : Class : Class : ...
メタクラスは(いまのところ)型名として使用できない。用途はあるか?
class App
def run(logger: Meta:Logger)
@logger = logger.new
end
end
App.new.run(FileLogger)
App.new.run(NullLogger)
# これでよくね?
# App.new.run(FileLogger.new)
# App.new.run(NullLogger.new)
使用できるようにするなら、記法を考える必要がある
class A
class B; end # フルネームは「A::B」
def foo(b: B, meta_b: Meta:B)
end
end
一見よさそうに見えるが、こういう例がある
class A
class B; end
def foo(local_b: B, global_B: ::B, meta_local_b: Meta:B, meta_global_B: ???)
end
class B; end
Shiika/specialize式
class A<T>
def foo
p Array<T>
end
end
A<Int>.foo #=> "Array<Int>"
A<String>.foo #=> "Array<String>"
- こうなってほしいが、現状ではどちらも
"Array<T>"
になるArray<T>
を「Array<T>
という名前の定数」として処理しているため
- 上記を実現するため、
<>
を演算子として捉え直す式1<式2>
をspecialize expressionと名付ける
- 式1,2には何が書けるべきか?
- 任意の式を許すとパーサが大変だし、書けても嬉しくなさそう
# 式2を動的にしたいことはあるか?
cls = [Int, String].sample
Array<cls>.new
# 型引数は静的な型チェックに使うためのものなので、実行時に指定できても嬉しくなさそう
# 式1を動的にできるか?
cls = [A, B].sample
cls<Int>.new
# これを実現するには、AとBの型パラメータの個数が同じであるという保証が必要(現状はそのような仕組みはない)