この記事はScala Advent Calendar 2017の15日目の記事になります。
#概要
Scala次期バージョンとして順調にリリースが続いているDotty。
今のうちに少し触ってみようと思い立ったものの、Windowsに対する公式サイトのサポートはあまり親切ではありません…。パッケージマネージャはhomebrewしか対応しておらず、zipをダウンロードしてみれば各種コマンドはbashで提供されているのみ。
というわけで、Windowsでお手軽にDottyを試してみるための方法をまとめました。
#前提
SBTがインストール済みでパスが通っているものとします。
Scalaを使用していれば自ずと満たしている条件かと思います。
SBTのバージョンは0.13系を使用しましたが、1.0系でも問題ないと思われます。
#Hello world
コマンドプロンプトで下記を実行します。
sbt new lampepfl/dotty.g8
プロジェクト名を聞かれるので入力すると、現在のフォルダ配下にプロジェクトが作成されます。
プロジェクトのフォルダに移動し、下記を実行。
sbt run
テンプレートプロジェクトの実行結果が表示されたと思います。めでたしめでたし。
sbtがDotty環境をお膳立てしてくれるので、別途インストールしたりする必要はないのでした。
#IDE
実行環境は整ったものの、静的型付け言語はIDEを使ってナンボ。
公式に推奨されているVisual Studio Codeに加え、IntelliJ IDEAでの対応方法を確認してみます。
##Visual Studio Code
Visual Studio Codeをダウンロードしてインストール。
インストール時の設定は特に弄らなくても良さそうです。
インストール後、コマンドプロンプトで先ほど作成したプロジェクトのフォルダに移動し、下記コマンドを実行します。
sbt launchIDE
Visual Studio Codeで該当プロジェクトを開きつつ、Visual Studio Codeで必要なプラグインのインストールまでやってくれます。
##IntelliJ IDEA
WindowsでScalaを触っていればおそらくお世話になっているであろうIntelliJ IDEA。
調べてみると、LSP SupportというLanguage Server Protocol用のプラグインが存在しました。早速インストールして設定を行います。
設定はメニューのFile -> Settings -> Languages&Frameworks -> Language Server Protocolにあります。
Server Definitionsに下記を設定すればOKです。
- Extension
- scala
- Artifact
- ch.epfl.lamp:dotty-language-server_0.5:0.5.0-RC1
- Main class
- dotty.tools.languageserver.Main
- Args
- -stdio
上記設定に加え、scalaプラグインと処理が競合するのでscalaプラグインを無効にしておく必要があります。
IDEAの再起動後に設定が有効になります。
再起動後、ステータスバー右端に緑の丸が表示されていればOKです。
先のプロジェクトを開き、Main.classを表示すると、宣言へのジャンプやオートコンプリートが動作していることが確認できます。
ただし、自分の環境では頻繁にタイムアウトが発生しました。
また、コードの色分けができなかったりオートコンプリート等も若干残念な感じだったり、色々なところで難があります。
scalaプラグインと共存できないのが痛いので、しばらくは様子見となりそうです。
#Dottyを試す
テンプレートのMain.scalaだとDottyならではのコードが何一つ存在しないため、下記のように編集してみます。
object Main {
case class User(name: String)
case class Group(name: String, users: Seq[User])
val users: Seq[User] = Seq(
User("user1"),
User("user2"),
User("user3")
)
val groups: Seq[Group] = Seq(
Group("group1", Seq(users(0))),
Group("group2", Seq(users(1), users(2)))
)
def search(name: String): Option[User | Group] = {
val user = users.find(_.name == name)
val group = groups.find(_.name == name)
user orElse group
}
def main(args: Array[String]): Unit = {
println(search("user2"))
println(search("group2"))
println(search("group5"))
}
}
Union typesを試してみました。もうちょっといい例はないものかと思いますが…。
実行結果は以下のようになります。
Some(User(user2))
Some(Group(group2,List(User(user2), User(user3))))
None
#終わりに
言語仕様としては魅力的なDottyですが、Visual Studio Codeを使用してもIDEサポートはまだまだのように感じられました。
IntelliJ IDEAのScalaサポートが手厚いため、相対的にそう感じられるだけかもしれませんが…。
正式版がリリースされる頃にはこのあたりの問題も解決しているといいなあ、と思います。