yhara.jp

Recent Posts

処理系ミートアップ #4

2021-07-10
Event

最近やったこと

Shiika/型名、定数名、クラス名

  • メソッドの引数にs: Stringと書いたとき、Stringは型名
  • String.newと書いたとき、Stringはクラス名
  • また、定数::Stringの参照でもある

一般に

  • クラスAを定義したとき、 -「型A」は「Aのインスタンスであるオブジェクト」を表す。
    • 定数::Aが定義され、その値はAのクラスオブジェクトで、その型はMeta:A
  • メタクラス
    • クラスオブジェクトのクラス
    • クラスごとに別の型になる(A.newB.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の型パラメータの個数が同じであるという保証が必要(現状はそのような仕組みはない)

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author