newキーワードを不要にする「クリエイターアプリケーション」とは?:Scala 3のパワーアップした表現力(4)

Scala 3 (Dotty 0.26.0-RC1)
最終更新:2020年9月9日

[AD] scalapediaでは記事作成ボランティアを募集しています

この記事では、Scala 3(Dotty)で導入された「クリエイターアプリケーション」という機能について解説します。

newキーワード無しにクラスをインスタンス化できる機能「クリエイターアプリケーション」

Scala 3では、単純な関数の呼び出し構文を使用して、クラスをインスタンス化することができます。

class File(s: String) { def this() = this("") } File("abc") // same as new File("abc") File() // same as new File()

この機能は「クリエイターアプリケーション機能」と呼ばれています。

new を省略することで実装の詳細を隠すことができ、コードがより読みやすくなります。 case classには既にあるこの機能はよく活用されており、実情として、case classを「newを書かなくてよくする」ためだけに定義する例が多く見受けられるほどでした。

今回、これまでcase classに対してのみ提供されてきた「newを省略する」という機能を一般のクラスにも追加しました。 わざわざcase classを使わなくてもnewを書かなくてよくなったというのがポイントです。

「クリエイターアプリケーション」という新しい規則が生まれてしまったものの、case classと同じ機能が普通のクラスにも備えられたことにより、覚える側としてはシンプルになりました。

クリエイターアプリケーションの仕組みはcase classとは異なる

さて、ここから先は細かい話になります。

普通のクラスとcase classとでは、newキーワードなしに新しいインスタンスを生成できるという挙動は同じように見えます。
しかし、これを実現する仕組みはそれぞれ異なります。

case classでは、コンパイラが自動的にapply メソッドを生成しています。 普通のクラスにおいては、コンパイラは関数呼び出し f(args) に対して新しい解釈をするようになりました。

これまでは、関数呼び出し f(args) が与えられた場合、以下の3つの規則を順次適用していました。

  • fargs に適用可能なメソッドである場合、そのまま f(args) として解釈する
  • そうでなければ、fargs に適用可能な apply メソッドをメンバとして持っている場合は、f.apply(args) として解釈する
  • そうでなければ、fp.mの形式で、pに適用可能な暗黙の変換cがあり、c(p).margsに適用可能である場合は、c(p).m(args)として解釈する

クリエイターアプリケーション機能の実現のため、これらの規則に続く第4の規則が作られました。

  • そうでなければ、fが構文的に安定した識別子であり、fを型識別子として解釈した場合のnew fargsに適用可能な場合、新しいf(args)として解釈する

同様に、型引数f[targs]を持つ関数呼び出しの可能な解釈は、最終的なフォールバックとして以下の解釈で拡張されます。

  • fが構文的に安定した識別子であり、型識別子として解釈した場合のnew f[targs]が実際に型付けられていれば、new f[targs]として解釈する

サイト内検索