次世代Scala「Dotty」 3つのねらい・7つの新しさをご紹介

Scala 3.3.1
最終更新:2020年9月28日

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

この記事では、Scala 3(コードネーム:Dotty)が実現する3つのねらい、7つの変化について紹介します。

Scala 3に関して、開発の進捗状況については以下の記事をご覧ください。

3つの狙いとは

Martin Odersky教授と開発チームは、オブジェクト指向プログラミングと関数型プログラミングをScala 2よりもさらに高いレベルで統合してさらに使いやすいものとするために、DOT計算の研究やそれに続くDottyの開発が続けてきました。

Dottyを開発して次世代のScalaとすることの狙いは、大きく分けると3つのポイントとなります。

  • DOT計算に関する基礎研究の成果を反映して、Scalaの基礎をより確固たるものとする
  • 強力だが扱いにくさもあったimplicitなどの機能を洗練させて理解しやすいものとし、Scalaをさらに簡単で安全に使えるようにする
  • Scalaの言語構造をさらに一貫性の高い表現力豊かなものとする

7つの変化とは

この狙いを実現した結果、Scala 2からScala 3へはひじょうに様々なことが変化することとなりました。

その変化は、大きくは以下の7つに分けられます。

  • 基礎固め
  • 単純化
  • 制約の追加
  • 機能の削除
  • 機能の変更
  • 新機能の追加
  • 新しいメタプログラミング

基礎固め

フルモデルチェンジに伴い、Scala自体の理論的な強化が試みられています。

以下の4つの新機軸を導入することにより、高階型や暗黙の関数型といったDOTの中核的な機能をScalaでも実現できました。

  • 交差型
  • 合併型
  • 型ラムダ
  • コンテキスト関数

交差型(Intersection Types)

複合型withを置き換える形で、「交差型」を表す&が導入されました。

既にある機能の代替ではあるので、一般のScala利用者にとっては地味な変更ではあります。
しかしながら、Scala本体や一部のライブラリ作者などScalaのパワーユーザーにとっては強力な支援となるでしょう。

合併型(Union Types)

「合併型」を表す|が導入されました。交差型と対になる概念です。

以下のような書き方ができるようになりました。
findUserメソッドの引数に着目してください。

case class UserId(value: Int) extends AnyVal case class Email(value: String) extends AnyVal case class User() def findUser(id: UserId | Email): User = { id match { case UserId(value) => lookupById(value) case Email(value) => lookupByEmail(value) } }

詳しくは以下の記事をご覧ください。

型ラムダ

「型ラムダ」を表す =>> が導入されました。
高階型コンストラクタを記述しやすくなり、高度な開発者の痒い所に手が届くようになりました。

コンテキスト関数

単純化

トレイトパラメータ

所与(given)インスタンス

using

拡張メソッド

非透過型エイリアス

トップレベル定義

Scala 3.0からは、トップレベルにさまざまな定義ができるようになります。

可変長引数パターン(Vararg Patterns)

クリエイターアプリケーション(Creator Application)

制約の追加

暗黙の型変換

所与のインポート

型射影

Scala 3より、抽象型を型射影することができなくなります。

多元的同一性

@infix@alpha

機能の変更

Structural Types

名前によるパターンマッチ

イータ変換 (eta expansion)

Implicit Resolution

新機能の追加

列挙型(Enums)

列挙型については既にこちらの記事で解説しています。

Parameter Untupling

依存関数型 (Dependent Function Types)

多相関数型 (Polymorphic Function Types)

カインド多相 (kind polymorphism)

新しいマクロでのメタプログラミング

マッチ型

インライン

クォートとスプライス

型クラス導出

名前渡しコンテキストパラメータ

その他の変更点

22個制限(Limit 22)

タプルやメソッド引数に掛かっていた22個制限は撤廃されます。
これにより23個以上の要素をもつタプルや、23個以上の引数を受け取るメソッドを手軽に扱えるようになりました。

機能の削除

多くの機能が削除されたり、他の機能で代替されたりしています。
詳しくはこちらの記事を参照するか、個別の記事をご覧ください。

複合型 (compound types)

上述のように、複合型は、よりパワーアップした「交差型」に置き換えられます。

DelayedInitトレイト

Appトレイトが継承していたDelayedInitトレイトは廃止されます。
Scala 3.0には実装されませんでした。
代替手段は用意されていません。
Appトレイトの使用箇所には影響があるので注意してください。

存在型(Existential Types)

forSomeキーワードを使用した存在型は廃止され、使用しない場合も限定的なサポートとなります。
代替として経路依存型を使用してください。

手続き型構文(Procedure syntax)

以下のような手続き型構文は廃止されます。

def f() { ... }

Scala 3.1までに書き換えてください。

クラスシャドウイング(Class Shadowing)

クラスシャドウイングは、継承先の内部クラスと同名の内部クラスを定義してオーバーライドせずに上書きする機能です。
クラスシャドウイングは3.0にて廃止されるので、名前を変更するなどして対応する必要があります。

XMLリテラル

XMLリテラルは将来的に廃止されます。
文字列補間にxml補間子(xml" ... ")が導入される計画があります。

シンボルリテラル

シンボルリテラル(例:'symbol)は廃止されます。
シンボルオブジェクト(Symbol)に置き換えられますが、いずれシンボルオブジェクトも廃止されます。

自動適用 (auto application)

自動適用とは、()付きで定義したメソッドを()なしでも呼び出せる機能です。
詳しくは以下の記事を参照してください。

弱適合 (weak conformance)

「弱適合」は、数値型をとるリストの型が揃わない場合に、他の数値型へ自動的に変換する機能です。
弱適合は必要以上に強力だったので廃止されることになりました。
Intのみを対象とする、より穏やかな機能に置き換えられました。

Auto tupling

(WIP)

do-while文

do-while文は廃止されます。
while文で書き直してください。

先行初期化(Early Initializers)

トレイトにパラメータを渡せないことの回避策として行われてきた「先行初期化」は廃止されました。
3.0より導入されたトレイトパラメータを使用しましょう。

Scala 2のマクロ

Scala 2のマクロは廃止され、Scala 3用の新しいマクロが導入されました。

大域脱出(Nonlocal Returns)

大域脱出は非推奨となりました。

[this]修飾子

private[this]protected[this]は廃止されました。

パッケージオブジェクト

上述のように、トップレベル定義が可能となるため、パッケージオブジェクトは廃止されます。

移行について

サイト内検索