2007年12月21日金曜日

Scala

Java Posse の Martin Odersky の interview から、Scala の作者である
だけではなく 1.3 以降の javac の開発もやってきた人だと関心。Scala
自身は初見だったが、よく pod cast にでてきたのは覚えている。言語に
うるさい人には気になるようだ。

Scala のコンパイラ、実行環境はオープンソースでダウンロードできて、
1.4 あたりからの java があれば実行できる。

* Hello World

package hello;
object HelloWorld {
def main(args: Array[String]) {
println("Hello World!")
}
}

- package は java と同様
- object Name { ... } は Name というシングルトンを作る
- メソッドの定義は def ではじめる。引数は "名前: 型" で宣言する
- println は組み込み
- import も同様に使えるが、機能が拡張されている。最後の要素で
{class1, class2} のようにまとめて指定でき、import a.b.C._ で
C がクラス名とすると、これは C に関する static import として
働く。

- ソースの拡張子は .scala, scalac でコンパイル。ファイル名とクラス名の
 一致の必要はないようだ。

* クラス定義

class Complex(real: double, imaginary: double) {
def re = real
def im = imaginary
override def toString() =
"" + re + (if (im < 0) "" else "+") + im + "i"
}

クラス名のあとに引数のリストが来る。これは primary constructor の
シグネチャで、class の body がパースされる。ボディがパースされるのは
ruby に似ている。

def re = real

は初期値の設定と re という getter/setter の宣言でもある。プロパティを
作っているといってもいいかも知れないが、うるさい人は色々と意見がある
だろう。本当のプロパティはコンポーネントモデルにおけるプロパティであり、
参照、設定のほかにもイベント機能なども備えないとなど云々...

Ruby のように自明なものは関数のあとに () を書かなくても呼べる。
またオブジェクトのオペレーションを呼ぶときに "." すら省略できるケースが
ある。

インスタンス化は java とほぼ同じ。

val c = new Complex(1.2, 3.4)

これは厳密に書けば

val c: Complex = new Complex(1.2, 3.4)

* Generics / Genericity

Generics/Template 相当の機能を備えている。Genericity と呼んでいる。
下の例では a は任意の型。

class Reference[a] {
private var contents: a = _
def set(value: a) { contents = value }
def get: a = contents
}

* Mixin 機能。

Ruby のものと似ている。AOP の手法の一つともいえる。実態つき、拡張可能な
インターフェイスのようなものと言ってもいい。

* call-by-value/call-by-name

関数呼び出しは call-by-value と call-by-name があり、引数の評価の
仕方が異なる。デフォルトは call-by-valude であるが、reduction が
完了しない事がある。その場合にはパラメータの型の前に => を入れると
call-by-name になる。

def constOne(x: Int, y: => Int) = 1

* if-else は conditional expression の様にも使える。

def abs(x: Double) = if (x >= 0) x else x

* Unit は java の void とほぼ同様。()

* Nested function

inner class の様に関数の中に関数を定義できる。一番外側の関数の変数は
nested function からも参照できる。

* Tail Recursion

一見、再起呼び出しに見えても、スタックを余計に消費しないように実行できる
場合はそうしてくれる。

* First-Class Functions

関数は first-class value と呼ばれ、他の関数に渡すことができる。そのような
関数を受け取ったり、返したりする関数は higher-order functions と呼ばれる。

関数のパラメータの型は "Int => Int" (Int をとり Int を返す) という形で
指定できる。その例として下のものは a から b の間の値に f 適用してその
合計をとる関数となる。

def sum(f: Int => Int, a: Int, b: Int): Int =
if (a > b) 0 else f(a) + sum(f, a + 1, b)

def sumInts(a: Int, b: Int): Int = sum(id, a, b)
def sumSquares(a: Int, b: Int): Int = sum(square, a, b)
def sumPowersOfTwo(a: Int, b: Int): Int = sum(powerOfTwo, a, b)

def id(x: Int): Int = x
def square(x: Int): Int = x * x
def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x 1)

0 件のコメント: