M.Hiroi's Home Page

Scala Programming

[ Home | Java ]

WHAT'S NEW


CONTENTS


お気楽 Scala プログラミング入門

CONTENTS

●入門編

●オブジェクト指向編編

●応用編

●パズルの解法


はじめに

Scala はスイス連邦工科大学 (EPFL) の Martin Odersky 教授によって設計されたプログラミング言語です。Scala はオブジェクト指向言語と関数型言語を統合した言語で、Java プラットフォーム (Java 仮想マシン) 上で動作します。Scala のオブジェクト指向はクラスベースで、継承は「単一継承」のみサポートしています。「多重継承」はサポートされていませんが、そのかわり Trait (トレイト) を使って Ruby のような Mix-in (ミックスイン) が可能です。また、Java と簡単に連携できるので、Java のライブラリ資産を有効に活用することができます。

Scala は強く型づけされた言語で、コンパイル時に静的な型チェックを行うことで、多くのエラーを検出することができます。Scala には ML (SML/NJ, OCaml) や Haskell などの関数型言語で有名な「型推論」という機能があるので、型宣言を省略してプログラムを簡潔に記述することができます。もちろん、パターンマッチング、クロージャ、カリー化など、関数型言語でよく使われている便利な機能がサポートされています。

M.Hiroi は Scala でプログラミングするのは初めてです。また、Java にも詳しいわけではないので、いきなり Scala に挑むのは無謀なことなのかもしれません。そこで、最初は M.Hiroi が知っている関数型言語の機能を中心に、簡単なプログラムを作りながら Scala を勉強していきたいと思っております。なにぶん初心者が作るプログラムなので、間違いや Scala の作法に反することがあるかと思います。何かお気づきの点がありましたらご指摘お願いいたします。たいしたことはできませんが、よろしければお付き合いくださいませ。

●インストール

Scala を実行するには Java の実行環境が必要です。M.Hiroi は OpenJDK 11 を使っています。Java のインストールは拙作のページ お気楽 Java プログラミング入門 - はじめに - Java のインストール をお読みください。

Scala は次のサイトからダウンロードできます。

上記サイトでも説明されているように、最近は Scala のビルドツール sbt を使ってインストールするのが主流のようですが、本稿では Download - Other resources にある Archive を利用することにします。Windows の場合、インストーラー (msi installer) が用意されているので、とても簡単にインストールすることができます。Unix 系 OS の場合、scala-2.13.5.tgz (2021 年 3 月時点) をダウンロードして展開します。

たとえば、ディレクトリ ~/scala/ で scala-2.13.5.tgz を展開すると、サブディレクトリ scala-2.13.5 が生成されます。あとはサブディレクトリ bin にパスを通すだけです。次のコマンドを実行してください。

export PATH=~/scala/scala-2.13.5/bin:$PATH

これでパスを通すことができます。上記のコマンドはファイル ~/.bashrc に追加しておくといいでしょう。

●プログラムの実行

Scala はプログラムをコンパイルするコマンド scalac と、コンパイルしたプログラムを実行するコマンド scala があります。これは Java のコマンド javac, java と同じ関係です。また、引数を指定せずにコマンド scala を実行すると、対話モード (REPL : Read-Eval-Print-Loop) で Scala を使用することができます。

$ scala
Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 11.0.10).
Type in expressions for evaluation. Or try :help.

scala>1 + 2 * 3
val res0: Int = 7

scala> :quit
$

REPL で Scala のプログラムを入力して簡単に実行することができます。終了する場合はコマンド :quit (または :q) か CTRL-D を入力してください。

次はお馴染みの Hello, world! を表示するプログラムを作ってみましょう。

リスト : hello.scala

object Hello {
    def main(args: Array[String]): Unit = {
        println("Hello, world!")
    }
}

ファイル名は hello.scala とします。拡張子は scala です。Scala の場合、Java とは違ってファイル名は object の名前 Hello と同じにする必要はありません。hello.scala でも test.scala でもかまいません。

プログラムのコンパイルは scalac で行います。シェルで scalac hello.scala と入力すると、hello.scala がコンパイルされて Hello.class という class ファイルが作成されます。ファイル名が test.scala の場合でもコンパイル後に生成されるファイルは Hello.class になります。プログラムの実行は scala を使います。コマンドプロンプトで scala Hello と入力します。object Hello のメソッド main が呼び出されて Hello, world! が表示されます。

$ scalac hello.scala
$ scala Hello
Hello, world!

また、次のように対話モードでプログラムをロードして、実行することもできます。

scala> :load hello.scala
val args: Array[String] = Array()
Loading hello.scala...
object Hello

scala> Hello.main(Array())
Hello, world!

scala>

なお、hello.scala は scalac でコンパイルしなくても、スクリプト言語のように実行することもできます。

$ scala hello.scala
Hello, world!

●簡単なベンチマーク

Scala のプログラムは Java 仮想マシン上で動作するので、JIT (Just in Time) コンパイラなどの技術によりプログラムを高速に実行することができます。その実行速度ですが、たらいまわし関数を使って調べてみました。

リスト : たらいまわし関数 (Scala)

object Tarai {
    def tak(x: Int, y: Int, z: Int): Int = {
        if (x <= y) z
        else tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y))
    }

    def main(args: Array[String]): Unit = {
        val start = System.currentTimeMillis
        println(tak(22, 11, 0))
        print(System.currentTimeMillis - start)
        println("msec")
    }
}
リスト : たらいまわし関数 (Java)

public class Tarai {
  static int tak(int x, int y, int z) {
    if(x <= y)
      return z;
    else
      return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
  }

  public static void main(String[] args) {
    long start = System.currentTimeMillis();
    System.out.println(tak(22, 11, 0));
    long end = System.currentTimeMillis();
    System.out.println((end - start)  + "ms");
  }
}

それでは実行結果を示します。tak(22, 11, 0) を計算しました。

表 : tak(22, 11, 0) の結果
処理系
Python (ver 3.6.9)69.6
Lua (ver 5.3.3)37.2
Ruby (ver 2.5.1p57)25.4
Gauche (ver 0.9.9)25.3
ocamlc (ver 4.05.0)10.8
SBCL (ver 1.4.5)6.38
LuaJIT (var 2.1.0-β)4.02
SML/NJ (ver 110.98)2.66
Julia (ver 1.3.0)2.02
GHC (ver 8.8.4)1.96
SBCL (最適化)1.57
GCC -O2 (ver 7.4.0)1.23
Scala (ver 2.13.5)1.07
ocamlopt (ver 4.05.0)0.97
Java (ver 11.0.10)0.95

Scala は GHC (Haskell) や SBCL (Common Lisp) よりも速く、GCC, OCaml, Java に匹敵する速度をたたき出しています。Scala は大変優れたコンパイラ (処理系) だと思います。興味のある方はいろいろ試してみてください。


初版 2014 年 7 月 20 日
改訂 2021 年 3 月 7 日

Yet Another Scala Problems


参考文献, URL

  1. The Scala Programming Language, (本家)
  2. Scala プログラミング入門, (神戸大学, 田村直之先生)
  3. スケーラブルで関数型でオブジェクト指向なScala入門, (@IT, 中村修太さん)
  4. ひしだま's ホームページ - Scalaメモ, (ひしだまさん)
  5. Scala研修テキスト, (株式会社ドワンゴ)

『お気楽 Scala プログラミング入門』の著作権は筆者「広井誠 (Makoto Hiroi) 」が保持します。無断使用や無断転載は禁止いたします。『お気楽 Scala プログラミング入門』で作成したプログラムはフリーソフトウェアとします。ご自由にお使いください。プログラムの改造や配布もご自由にどうぞ。その際は、出典を明記してくださるようお願いいたします。

ただし、これらのプログラムは無保証であり、使用したことにより生じた損害について、作者「広井誠 (Makoto Hiroi) 」は一切の責任を負いません。また、これらのプログラムを販売することで利益を得るといった商行為は禁止いたします。

Copyright (C) 2014-2021 Makoto Hiroi
All rights reserved.

[ Home | Java ]