オブジェクト指向から関数型プログラミングへ『Scala 入門 (Essential Scala)』第2章 式・型・値


[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) で公開されている [Essential Scala](https://underscore.io/books/essential-scala/) の [2 Expressions, Types, and Values](https://books.underscore.io/essential-scala/essential-scala.html#expressions-types-and-values) を日本語訳したものです。日本語訳においてもライセンスは同じものを継承しています。毎日少しずつ翻訳を進めており、最新の日本語訳は [Scala 入門 (Essential Scala)](http://takuya0301.github.io/essential-scala.html) にあります。

原書：[underscoreio/essential-scala](https://github.com/underscoreio/essential-scala)
訳書：[takuya0301/essential-scala-ja](https://github.com/takuya0301/essential-scala-ja)

# ライセンス

Written by [Dave Gurnell](http://twitter.com/davegurnell) and [Noel Welsh](http://twitter.com/noelwelsh). Copyright [Underscore Consulting LLP](http://underscore.io), 2015-2017.
Translated by [Takuya Tsuchida](http://twitter.com/takuya0301). Copyright Takuya Tsuchida, 2020.
![CC BY-SA 4.0 logo](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.

# 目次

[序文](https://qiita.com/takuya0301/items/ddbe5493273d317cbb06)
[第1章 はじめに](https://qiita.com/takuya0301/items/6528b130f43dc5a3cb48)
[第2章 式・型・値](https://qiita.com/takuya0301/items/08e3101f84193f9e7346)
[第3章 オブジェクトとクラス](https://qiita.com/takuya0301/items/df373bf12a2560647c9e)
第4章 トレイトによるデータモデリング
第5章 シーケンス処理
第6章 コレクション
第7章 型クラス

# 第2章 式・型・値

本章では Scala プログラムの基本的な構成要素である**式 (expression)**・**型 (type)**・**値 (value)** について見ていきます。それらのコンセプトを理解することが Scala プログラムがどのように動くのかというメンタルモデルを形成するために必要です。

## 最初のプログラム

Scala コンソールか Scala ワークシートに `"Hello world!"` と入力し、コンソールでリターンキーを押下するかワークシートを保存してください。このようなインタラクションが見られるはずです。

```scala
"Hello world!"
// res0: String = Hello world!
```

このプログラムについてはいろいろ言えることがあります。それは特別に**リテラル式 (literal expression)** もしくは略してリテラルと呼ばれる単一の式で構成されていることです。

Scala は私たちのプログラムを実行（評価）します。Scala コンソールや Scala ワークシートでプログラムを評価するとき、プログラムの**型**とプログラムを評価した**値**という2つの情報を受け取ります。この場合は、型が `String` で、値が `"Hello world!"` です。

プログラムが生成した出力値 "Hello world!" はプログラムと同じに見えますが、その2つの間には違いがあります。リテラル式は入力したプログラムテキストである一方、コンソールが表示したものはプログラムを評価した結果です。（リテラル (literal) は、評価されたものがその文字通り (literally) に見えるので名付けられました。）

わずかに複雑なプログラムを見てみましょう。

```scala
"Hello world!".toUpperCase
// res1: String = HELLO WORLD!
```

このプログラムは**メソッド呼び出し (method call)** を加えることによって最初の例を拡張したものです。Scala における評価は左から右へ進みます。この例では、最初にリテラル `"Hello world!"` が評価されます。次に、その評価された結果に対しメソッド `toUpperCase` が呼ばれます。このメソッドは文字列値を大文字に変換したものを新しい文字列として返します。これがコンソールによって表示された最終的な値です。

繰り返しになりますが、このプログラムの型は `String` で、この場合はプログラムが `"HELLO WORLD!"` に評価されます。

### コンパイル時と実行時

Scala プログラムが通過する明確な2つの段階があります。最初が**コンパイル (compile)** で、コンパイルが成功していれば、次が**実行 (run)** または評価です。最初のステージを**コンパイル時 (compile-time)**、次のステージを**実行時 (run-time)** と呼びます。

Scala コンソールを使用しているとき、プログラムはコンパイルしてすぐに評価されるので、1つの段階だけがあるような印象を抱かせます。型と値の間における違いを正しく理解するためにも、コンパイル時と実行時がまったく異なることを理解するのは重要です。

コンパイルはプログラムが意味をなしているかを検証する工程です。プログラムが「意味をなす」には2つの観点が必要です。

1. プログラムは**文法的に正確 (syntactically correct)** でなければなりません。それはプログラムの部品が言語の文法に従っているということを意味します。"on cat mat sat the"（猫の上敷き物座った）は文法的に正確ではない英文の例です。これは文法的に正確ではない Scala プログラムの例です。

    ```scala
    toUpperCase."Hello world!"
    // <console>:2: error: identifier expected but string literal found.
    // toUpperCase."Hello world!"
    //             ^
    ```

2. プログラムは**型検証 (type check)** されなければなりません。意味をなすプログラムであるということは、プログラムがある制約に従っているということを意味します。"the mat sat on the cat"（敷き物は猫の上に座った）は文法的に正確ですが意味がわからない英文の例です。これは数値を大文字に変換しようとして型検証に失敗するシンプルなプログラムです。

    ```scala
    2.toUpperCase
    // <console>:13: error: value toUpperCase is not a member of Int
    //        2.toUpperCase
    //          ^
    ```

大文字小文字という概念は数値について意味をなさないので、型システムはこのエラーを捕捉します。

プログラムがコンパイル時の検証を通過した場合、次にプログラムは実行されるかもしれません。実行はコンピューターがプログラムにある指示を実行する工程です。

プログラムのコンパイルが成功したとしても、実行時に失敗する可能性が残っています。整数を0で割ると Scala では実行時エラーが発生します。

```scala
2 / 0
// java.lang.ArithmeticException: / by zero
//   ... 342 elided
```

整数の型 `Int` はプログラムの型検証を通過すれば割り算できます。しかし、割り算の結果を表現できる `Int` が存在しないので、実行時にプログラムは失敗します。


### 式・型・値

それでは、式・型・値とは正確には何でしょうか？

式はファイルやコンソール、ワークシートに入力したプログラムテキストの一部です。それは Scala プログラムの主要な構成要素です。のちほど、**定義 (definition)** や**文 (statement)** と 名付けられた他の構成要素も見ていきます。式はコンパイル時に存在します。

式の特徴を定義すると、それは値に評価されるということです。値はコンピューターのメモリに保持されます。それは実行時に存在します。例えば、式 `2` は、コンピューターのメモリの、特定の場所の、特定のビット列に評価されます。

私たちは値を用いて計算します。値はプログラムが受け渡したり操作したりする実体です。例えば、2つの数値の最小値を計算するために、下記のようなプログラムを書くでしょう。

```scala
2.min(3)
// res4: Int = 2
```

ここに2つの値 `2` と `3` があり、それらを `2` に評価されるより大きなプログラムに結合しています。

Scala において、すべての値は**オブジェクト (object)** で、のちほど見ていくように特定の意味を持ちます。

さて次に型のことを考えましょう。型はプログラム上の制約で、どのようにオブジェクトを操作できるかを制限します。すでに2つの型 `String` と `Int` を、そして型によって異なる操作を実行できることを見てきました。

この段階で、型についてもっとも重要な点は**式は型を持つが値は持たない**ということです。私たちはコンピューターのメモリの任意の部分を検査できませんし、それを生成したプログラムを知らずして、どのようにそれが解釈されるのかを予言できません。例えば、Scala で `Int` 型と `Float` 型はどちらもメモリの32ビットによって表現されます。しかし、与えられた32ビットを `Int` や `Float` として解釈すべきというタグやその他の表示はないのです。

実行時エラーを引き起こす式の型を教えてと、Scala コンソールに尋ねることによって、コンパイル時に型が存在することを明らかにできます。

```scala
:type 2 / 0
// Int
```

```scala
2 / 0
// java.lang.ArithmeticException: / by zero
//   ... 486 elided
```

式 `2 / 0` は、それを評価したときには失敗するにも関わらず、`Int` 型を持つことを見ました。

コンパイル時に存在する型は、値に一貫した解釈を与えるプログラムを書くように制約します。特定の32ビットが、ある時は `Int` で、またある時は `Float` であると断言はできません。プログラムの型が検証されたとき、Scala はすべての値が一貫して使用されることを保証するので、値の表現で型の情報を記録する必要がありません。型の情報を取り除くこの処理を**型消去 (type erasure)**[^type-erasure]と呼びます。

[^type-erasure]: これは完全に正しくはありません。Scala コードを実行するプログラムである Java 仮想マシンは2種類のオブジェクトを識別します。プリミティブ型は、値の表現と一緒にどんな型の情報も保持しません。オブジェクト型は型の情報を保持します。しかし、この型の情報は完全ではなく失われる場合もあります。それゆえに、コンパイル時と実行時の間にある区別を曖昧にすることは危険です。実行時にある型の情報を頼りにしない（本書ではそういうパターンを明らかにしていきます。）のであれば、それらの問題に遭遇することはないでしょう。

必然的に、型に合致する値について、考え得るすべての情報をその型は含みません。そうしないと、型検証はプログラムを実行することと等価になってしまいます。すでに見てきたように、型システムは `Int` をゼロで割ることを防ぐことはなく、それは実行時エラーを引き起こします。

Scala コード設計の主要部分は、型システムの利用において、どのエラーケースを無視したいのかを決定することです。型システムでたくさんの便利な制約を表現することで、プログラムの信頼性を向上させられることを見ていきます。もしプログラムにおいて十分に重要であると決定すれば、エラーの可能性を表現する型システムを使用した除算演算子を実装することができます。型システムを上手に使用することは本書における重要なテーマのひとつです。


### 覚えておいてほしいこと

Scala を使用するのであれば、Scala プログラムのメンタルモデルを構築しなければなりません。このモデルにおける3つの基本的な構成要素は**式**・**型**・**値**です。

式は値に評価されるプログラムの部品です。Scala プログラムの主要な部品になります。

式は型を持ち、プログラムの制約を表現します。**コンパイル時**にプログラムの型は検証されます。型に一貫性がない場合、コンパイルは失敗し、プログラムを評価（実行）することはできません。

値はコンピューターのメモリに存在し、実行中のプログラムが操作するものです。Scala におけるすべての値は**オブジェクト**で、その意味はのちほど議論します。


### 演習

#### 型と値

Scala コンソールか Scala ワークシートを使用して、下記の式の型と値を特定してください。

```scala
1 + 2
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
型は `Int` で値は `3` です。
</div></details>

```scala
"3".toInt
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
型は `Int` で値は `3` です。
</div></details>

```scala
"foo".toInt
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
型は `Int` ですが、これは値に評価されません。その代わりに例外が発生し、発生した例外は値ではありません。これをどう理解すればいいでしょうか？式の結果による計算を続けられないということです。例えば、それを印字することはできません。

```scala
println("foo")
// foo
```

と

```scala
println("foo".toInt)
// java.lang.NumberFormatException: For input string: "foo"
//   at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
//   at java.lang.Integer.parseInt(Integer.java:580)
//   at java.lang.Integer.parseInt(Integer.java:615)
//   at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:272)
//   at scala.collection.immutable.StringOps.toInt(StringOps.scala:29)
//   ... 730 elided
```

を比較してみてください。後者でどんな印字も発生しないことは、`println` が評価されないということを示しています。
</div></details>

## オブジェクトとの相互作用


前節では Scala プログラムの基本的な構成要素である式・型・値を見てきました。また、**すべての値はオブジェクトである**ことも学びました。本節では、オブジェクトとオブジェクトに対してどのように相互作用するのかについて学んでいきます。

### オブジェクト

オブジェクトはデータとそのデータへの操作のグループです。例えば、`2` はオブジェクトです。データは整数の2で、データへの操作はなじみのある `+` や `-` などです。

オブジェクトのデータと操作について特別な専門用語があります。操作は**メソッド (method)** として知られています。データは**フィールド (field)** に保持されます。

### メソッド呼び出し

メソッド**呼び出し (call)** によってオブジェクトを作用させます[^patterns]。メソッド呼び出しの例をいくつかすでに見てきました。例えば、`String` の大文字版をその `toUpperCase` メソッドを呼び出すことによって取得できることを見ました。

```scala
"hello".toUpperCase
// res0: String = HELLO
```

一部のメソッドは**引数 (parameter)** を受け取り、それはメソッドがどのように動作するかを制御します。例えば、`take` メソッドは `String` から文字を取り出します。いくつの文字を取り出したいかを指定する引数を `take` に渡す必要があります。

```scala
"abcdef".take(3)
// res1: String = abc

"abcdef".take(2)
// res2: String = ab
```


---

#### :information_source: メソッド呼び出し文法

メソッド呼び出しのための文法は、

```scala
anExpression.methodName(param1, ...)
```

か

```scala
anExpression.methodName
```

です。ここで、

- `anExpression` はオブジェクトに評価される任意の式
- `methodName` はメソッドの名前
- `param1, ...` はメソッドの引数に評価される1つ以上の式

とします。

---

メソッド呼び出しは式なのでオブジェクトに評価されます。これは、より複雑なプログラムをつくるために、メソッド呼び出しを連鎖できるということを意味します。

```scala
"hello".toUpperCase.toLowerCase
// res3: String = hello
```

メソッド呼び出しにおける様々な式はどの順番で評価されるのでしょうか？メソッド引数は、メソッドが呼び出される前に左から右に評価されます。下記の式では、

```scala
"Hello world!".take(2 + 3)
// res4: String = Hello
```

最初に式 `"Hello world!"` が、次に `2 + 3`（これは、最初に `2` を、次に `3` を評価する必要があります。）が、そして最後に `"Hello world!".take(5)` が評価されます。

### 演算子

Scala においてすべての値はオブジェクトであるため、`Int` や `Boolean` のようなプリミティブ型についてもメソッドを呼び出すことができます。これは `int` や `boolean` がオブジェクトではない Java と対照的です。

```scala
123.toShort // これは Scala で `Short` を定義する方法です
// res5: Short = 123

123.toByte // これは `Byte` を定義する方法です
// res6: Byte = 123
```

しかし、`Int` がオブジェクトであれば、`+` や `-` のような基本的な算術演算子は何でしょうか？それらもまたメソッドでしょうか？そうです。Scala のメソッドは英数字の名前と同じようにシンボルの名前を持つことができます。

```scala
43 - 3 + 2
// res7: Int = 42

43.-(3).+(2)
// res8: Int = 42
```

（Scala 2.10 以前においては、`43.` を `Double` として解釈されることを防ぐために、`(43).-(3).+(2)` と書く必要があるので注意してください。）

---

#### :information_source: 中置演算子記法

Scala において `a.b(c)` と書かれた任意の式は `a b c` と書けます。

`a b c d e` が等価であるのは `a.b(c).d(e)` で、`a.b(c, d, e)` ではないことに注意します。

---

シンボルの名前を持つか、英数字の名前を持つかにかかわらず、1つの引数を受け取るどんなメソッドでも**中置演算子記法 (infix operator notation)** を使用できます。

```scala
"the quick brown fox" split " "
// res: Array[String] = Array(the, quick, brown, fox)
```

中置記法は、いくつかの文法的速記のひとつで、冗長なメソッド呼び出しの代わりに、簡潔な演算子式を書くことを可能にします。**前置 (prefix)**・**後置 (postfix)**・**右結合 (right-associative)**・**代入演算子 (assignment-style)** という記法もありますが、中置記法に比べると一般的ではありません。

中置演算子の結合は何の優先順位規則を支持すべきか？という質問はそれ自身をもたらします。Scala は、数学や論理の直観的知識にならい、メソッド名として使用する識別子から得られる[優先順位規則](http://stackoverflow.com/questions/2922347/operator-precedence-in-scala)一式を使用します。

```scala
2 * 3 + 4 * 5
// res11: Int = 26

(2 * 3) + (4 * 5)
// res12: Int = 26

2 * (3 + 4) * 5
// res13: Int = 70
```

### 覚えておいてほしいこと

Scala のすべての値はオブジェクトです。それらの**メソッド呼び出しによってオブジェクトを作用**させます。Java を背景知識としているのであれば、`Int` や他の任意のプリミティブ値のメソッドを呼び出せることに注意してください。

メソッド呼び出しのための文法は、

```scala
anExpression.methodName(parameter, ...)
```

か

```scala
anExpression methodName parameter
```

です。

**Scala は非常に少ない演算子を持ち、ほとんどすべてはメソッド呼び出しです**。中置演算子記法のような文法規則をコードを簡潔かつ読みやすくするために使用しますが、標準のメソッド記法の方がわかりやすい場合はいつでもそれに戻すことができます。

のちほど見ていくように、式を伴うプログラミングにおける Scala の焦点は、Java で実現するよりさらに短いコードで書くことを可能にすることです。また、値と型を使用する非常に直観的な方法で、コードについての判断を可能にします。

### 演習

#### 演算子スタイル

演算子スタイルに書き直してください。

```scala
"foo".take(1)
// res14: String = f
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

```scala
"foo" take 1
// res15: String = f
```
</div></details>

メソッド呼び出しスタイルに書き直してください。

```scala
1 + 2 + 3
// res16: Int = 6
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

```scala
1.+(2).+(3)
// res17: Int = 6
```
</div></details>

#### 置換

下記の2つの式の間にある違いは何ですか？類似点は何ですか？

```scala
1 + 2 + 3

6
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
2つの式は同じ結果型と同じ返却値を持ちます。しかし、それらは異なった方法でその結果に辿り着きます。前者は一連の加算によってその結果を計算する一方、後者はただ単にリテラルです。

どちらの式も副作用を持たないので、ユーザー視点からそれらは交換可能です。`1 + 2 + 3` と書けるところはどこでも `6` と書け、どんなプログラムの意味も変えることはありません。逆もまた同様です。これは**置換 (substitution)**（訳注：数学だと**代入**という訳語が一般的です。）として知られており、あなたは数式を簡単にする原理として学校で記憶しているかもしれません。

プログラマーとしてはコードがどのように動くのかというメンタルモデルを養う必要があります。**評価の置換モデル**は目に入る式はどれでもその結果と置換して構わないというとりわけ単純なモデルです。副作用がないことで、式の置換モデルはいつでも機能します[^side-effects]。式の各構成要素である型と値を知っていれば、式全体としての型と値を知っています。関数型プログラミングにおいて副作用を避けようと努力している理由は、それがプログラムを容易に理解できるようにするからです。
</div></details>

[^side-effects]: 副作用とは正確には何でしょうか？ひとつの実用的な定義は、間違った結果を置換によって生じさせてしまう何かのことです。副作用がなければ、置換は**必ず**機能するのでしょうか？Scala の本当に正しいモデルを示すには、置換を適用する順番を定義する必要があります。いくつかの考えうる順番があります。（例えば、置換を左から右へ実行するのか、右から左へ実行するのか？置換をできるだけ早くするのか、値が必要になるまで遅延するのか？）ほとんどいつも置換の順番は問題になりませんが、それが問題になる場合もあります。Scala はいつも「左から右へ」「できるだけ早く」置換を適用します。

[^patterns]: パターンマッチングと呼ばれるオブジェクトを作用させる別の方法があります。パターンマッチングはのちほど紹介します。

## リテラルオブジェクト

すでに Scala の基本型のいくつかを取り上げました。本節では、Scala におけるすべての**リテラル式**を扱うことによって、その知識に磨きをかける予定です。リテラル式は「それ自身」が象徴する固定値を表現します。下記はひとつの例です。

```scala
42
// res0: Int = 42
```

この REPL での相互作用は、リテラル `42` が `Int` `42` に評価されることを示しています。

リテラルとそれが評価された値を混同してはいけません。リテラル式はプログラムを実行する前のプログラムテキストにおける表現で、値はプログラムを実行した後のコンピューターのメモリにおける表現です。

これまでにプログラミングの経験、とくに Java の経験があれば、Scala におけるリテラルに見覚えがあるはずです。

### 数値

数値は Java にある同じ型を共有しており、32ビット整数の `Int`、64ビット浮動小数点数の `Double`、32ビット浮動小数点数の `Float`、そして64ビット整数の `Long` があります。 

```scala
42
// res1: Int = 42

42.0
// res2: Double = 42.0

42.0f
// res3: Float = 42.0

42L
// res4: Long = 42
```

Scala は16ビット整数の `Short` と8ビットの `Byte` を持ちますが、それらを生成するためのリテラル文法はありません。その代わりに、`toShort` や `toByte` と呼ばれるメソッドを使用することで生成できます。

### 真偽値

真偽値は Java とちょうど同じで、`true` か `false` です。

```scala
true
// res5: Boolean = true

false
// res6: Boolean = false
```

### 文字値

`Chars` は16ビット Unicode 値で、シングルクォートで囲まれた単一の文字として書かれます。

```scala
'a'
// res7: Char = a
```

---

#### :information_source: Scala 対 Java の型階層

最初の文字が大文字で書かれていますが、Scala の `Int` や `Double`、`Float`、`Long`、`Short`、`Byte`、`Boolean`、`Char` は、Java の `int` や `double`、`float`、`long`、`short`、`byte`、`boolean`、`char` とちょうど同じものを参照します。

Scala において、それらすべての型はメソッドとフィールドを伴うオブジェクトのように振る舞います。しかしながら、一度コードがコンパイルされたら、Scala の `Int` は Java の `int` とちょうど同じです。これが2つの言語間の相互運用を簡単にしてくれるのです。

---

### 文字列値

文字列値はちょうど Java の文字列で、同じ方法で書かれます。

```scala
"this is a string"
// res8: String = this is a string

"the\nusual\tescape characters apply"
// res9: String =
// the
// usual    escape characters apply
```

### Null 値

Null 値は Java と同じであるにもかかわらず、ほとんど頻繁には使用されません。また、Scala の `null` は独自の `Null` 型を持ちます。

```scala
null
// res10: Null = null
```

---

#### :information_source: Scala で Null 値を使用する

`null` は Java コードで一般的ですが、Scala では非常に悪い習慣であると考えられています。

Java における `null` の主な用途は、プログラム実行の異なる時点において、値の有無という**任意 (optional)** 値を実装することです。しかしながら、`null` 値はコンパイラーによってチェックできないため、`NullPointerException` という形で実行時エラーが発生する可能性があります。

のちほど、コンパイラーによってチェックされる任意値を定義する手段を Scala が持つことを見ていきましょう。これは `null` を使用する必要性を取り除き、プログラムをより安全にしてくれます。

---

### Unit 値

Scala で `()` と書かれる Unit 値は、Java の `void` に相当します。Unit 値は、`println` を使用して標準出力に印字するような、何の面白みもない値に評価される式の結果です。コンソールは Unit 値を印字しませんが、式の型を尋ねることで、実際に何らかの式の結果であることがわかります。

```scala
()
```

```scala
:type ()
// Unit
```

```scala
println("something")
// something
```

```scala
:type println("something")
// Unit
```

Unit 値は Scala において重要な概念です。Scala の文法構造の多くは、型と値を持つ**式**です。有用な値を得られない式のためのプレイスホルダーが必要で、Unit 値はまさにそれを提供してくれます。

### 覚えておいてほしいこと

本節では、基本的なデータ型を評価する**リテラル**式を見てきました。これらの基本型は、等価なものがない `Unit` を除いて、ほとんど Java と同じです。

すべてのリテラル式は**型**を持ち、**値**に評価されることに注意してください。これは、より複雑な Scala の式にも当てはまります。

次節では、独自のオブジェクトリテラルを定義する方法を学びます。

### 演習

#### 文字通りただのリテラル

下記の Scala リテラルの値と型は何ですか？

```scala
42

true

123L

42.0
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

`42` は `Int` です。`true` は `Boolean` です。`123L` は `Long` です。`42.0` は `Double` です。

この演習は、Scala コンソールや Scala ワークシートを使用した体験をするだけです。
</div></details>

#### 引用と誤引用

下記のリテラルの違いは何ですか？それぞれの型と値は？

```scala
'a'

"a"
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

1つ目は `Char` リテラルであり、2つ目は `String` リテラルです。
</div></details>

#### 副作用についての余談

下記の式の違いは何ですか？それぞれの型と値は？

```scala
"Hello world!"

println("Hello world!")
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

リテラル式 `"Hello world!"` は `String` の値として評価されます。式 `println("Hello world!")` は `Unit` として評価され、副作用としてコンソールに `"Hello world!"` を印字します。

これは、値を評価するプログラムと、値を副作用として印字するプログラムとの間の重要な区別です。前者はより大きな式で使用できますが、後者は使用できません。
</div></details>

#### 失敗から学ぶ

下記のリテラルの型と値は何ですか？REPL や Scala ワークシートに書いてみて、何が起こるか見てみましょう！

```scala
'Hello world!'
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

エラーメッセージを見ることになるはずです。開発環境のエラーメッセージを読んで慣れることに時間をかけてください。すぐに他にもたくさん見るようになるので！
</div></details>

## オブジェクトリテラル

ここまでは、`Int` や `String` のような組み込み型のオブジェクトを作成し、それらを式に組み合わせる方法を見てきました。本節では、**オブジェクトリテラル (object literals)** を使用して独自デザインのオブジェクトを作成する方法を見ていきます。

オブジェクトリテラルを書くとき、式とは別のプログラムの一種である**宣言 (declaration)** を使います。宣言は値を評価しません。その代わりに名前と値を関連付けます。この名前は他のコードで値を参照するために使用できます。

下記のように空のオブジェクトを宣言できます。

```scala
object Test {}
```

これは値に評価されず式ではありません。むしろ、名前 `Test` を空のオブジェクト値に結び付けます。

一度 `Test` という名前に結び付ければ式の中で使用することができ、それは宣言したオブジェクトに評価されます。もっとも単純な式はそれ自身の名前だけで、それ自体が値として評価されます。

```scala
Test
// res0: Test.type = Test$@3f447ef3
```

この式は `123` や `"abc"` のようなリテラルを書くことと同じです。オブジェクトの型は `Test.type` として報告されることに注意してください。これは、これまで見てきた型とは異なり、オブジェクトのためだけに作成された新しい型で、**シングルトン型 (singleton type)** と呼ばれます。この型における他の値を作成することはできません。

空のオブジェクトはあまり便利ではありません。オブジェクト宣言の本体である中括弧の間には式を入れることができます。しかし、メソッドやフィールド、さらなるオブジェクトを宣言するような宣言を入れるのが一般的です。

---

#### :information_source: オブジェクト宣言文法

オブジェクト宣言のための文法は、

```scala
object name {
  declarationOrExpression ...
}
```

です。ここで、

- `name` はオブジェクトの名前
- `declarationOrExpression` は宣言か式（オプション）

とします。

---

それではメソッドとフィールドをどのように宣言するか見ていきましょう。

### メソッド

メソッドによってオブジェクトを作用させるので、メソッドを伴うオブジェクトを生成してみましょう。

```scala
object Test2 {
  def name: String = "Probably the best object ever"
}
```

ここでは `name` と呼ばれるメソッドを生成しました。これをいつもの方法で呼び出すことができます。

```scala
Test2.name
// res1: String = Probably the best object ever
```

下記はより複雑なメソッドを伴うオブジェクトです。

```scala
object Test3 {
  def hello(name: String) =
    "Hello " + name
}
```

```scala
Test3.hello("Noel")
// res2: String = Hello Noel
```

---

#### :information_source: メソッド宣言文法

メソッドを宣言するための文法は、

```scala
def name(parameter: type, ...): resultType =
  bodyExpression
```

か

```scala
def name: resultType =
  bodyExpression
```

です。ここで、

- `name` はメソッドの名前
- `parameter` はメソッドに与えられる引数の名前（オプション）
- `type` はメソッド引数の型
- `resultType` はメソッドの結果型（オプション）
- `bodyExpression` はメソッドを呼び出すことで評価される式

とします。メソッド引数はオプションですが、メソッドが引数を持つのであれば、それらの型は与えられなければなりません。結果型はオプションであるにもかかわらず、それを定義することが、機械的に検証されたドキュメントとしての役割を果たすので良い習慣とされます。

**引数 (argument)** という用語は**パラメーター (parameter)** と言い換えることができます。（訳注：本書ではどちらの用語も**引数**という訳語に統一しています。）

---

---

#### :information_source: 返却は暗黙的

メソッドの返却値は本体を評価することによって決定されます。Java でするように `return` を書く必要はありません。

---

### フィールド

オブジェクトは**フィールド (field)** と呼ばれる他のオブジェクトを含めることもできます。`def` によく似た `val` や `var` というキーワードを使用して導入します。

```scala
object Test4 {
  val name = "Noel"
  def hello(other: String): String =
    name + " says hi to " + other
}
```

```scala
Test4.hello("Dave")
// res3: String = Noel says hi to Dave
```

---

#### :information_source: フィールド宣言文法

フィールドを宣言するための文法は、

```scala
val name: type = valueExpression
```

か

```scala
var name: type = valueExpression
```

です。ここで、

- `name` はフィールドの名前
- `type` はフィールドの型（オプション）
- `valueExpression` は `name` に束縛されるオブジェクトに評価される式

とします。

---

`val` を使用することで**不変 (immutable)** フィールドを定義でき、これは名前に束縛された値の変更ができないことを意味します。`var` は**可変 (mutable)** フィールドで、束縛された値の変更ができます。

**常に `var` より `val` を選びましょう。** 置換を維持するため、Scala プログラマーは可能な限り不変フィールドを使用することを選びます。アプリケーションコードで時折可変フィールドを生成することは間違いありませんが、本書の大部分では `var` を使用しないようにしており、普段の Scala プログラミングにおいてもそれに倣いましょう。

### メソッド対フィールド

同じ動作をするように見える引数のないメソッドを持つことができるにも関わらず、なぜフィールドが必要なのか不思議に思うかもしれません。その違いはわずかで、フィールドは値に名前を与えますが、一方のメソッドは値を算出する計算に名前を与えます。

その違いを明らかにするオブジェクトがこちらです。

```scala
object Test7 {
   val simpleField = {
     println("Evaluating simpleField")
     42
   }
   def noParameterMethod = {
     println("Evaluating noParameterMethod")
     42
   }
}
```

ここでは、コンソールに何かを印字するために `println` 式を、式をグループにするためにブロック式（`{` と `}` によって囲まれた式）を使用しています。なお、ブロック式については、次節でより詳しく見ていきます。

オブジェクトを定義したとコンソールに表示されているのに、いずれの `println` 文も実行されていないことに注意してください。これは**遅延読み込み (lazy loading)** と呼ばれる Scala と Java の特性によるものです。

オブジェクトやクラス（後述）は、他のコードによって参照されるまで読み込まれません。これが、単純な `"Hello world!"` アプリを実行するために、Scala が標準ライブラリ全体をメモリに読み込むことを防いでいます。

式の中で `Test7` を参照することで、Scala にオブジェクトの本体を強制的に評価させてみましょう。

```scala
Test7
// Evaluating simpleField
// res4: Test7.type = Test7$@3a39aa95
```

オブジェクトが最初に読み込まれるとき、Scala はその定義を実行し、各フィールドの値を計算します。その結果、コードの副作用として `"Evaluating simpleField"` が印字されます。

**フィールドにおける本体の式は一度だけ実行されます。** その後、オブジェクトにその最終的な値が格納されます。下記で `println` 出力が欠けていることからわかるように、その式は二度と評価されることはありません。

```scala
Test7.simpleField
// res5: Int = 42

Test7.simpleField
// res6: Int = 42
```

一方、下記で `println` 出力が繰り返されていることからわかるように、メソッドの本体はメソッドを呼び出すたびに評価されます。

```scala
Test7.noParameterMethod
// Evaluating noParameterMethod
// res7: Int = 42

Test7.noParameterMethod
// Evaluating noParameterMethod
// res8: Int = 42
```

### 覚えておいてほしいこと

本節では、独自のオブジェクトを作成し、メソッドとフィールドを与え、式の中で参照しました。

文法としてオブジェクトの宣言、

```scala
object name {
  declarationOrExpression ...
}
```

メソッドの宣言、

```scala
def name(parameter: type, ...): resultType = bodyExpression
```

そしてフィールドの宣言、

```scala
val name = valueExpression
var name = valueExpression
```

を見てきました。これらすべては**宣言**で、名前と値を束縛します。宣言は式とは異なります。宣言は値を評価しませんし型も持ちません。

また、メソッドとフィールドの違いを見てきました。フィールドはオブジェクトの中に格納された値を参照し、一方のメソッドは値を算出する計算を参照します。

### 演習

#### キャット・オ・マティック

下記の表は、3匹の猫の名前 (name)・色 (colour)・好きな食べ物 (food) を示しています。それぞれの猫についてのオブジェクトを定義してください。（経験豊富なプログラマーの方へ：クラスについてはまだ説明していません。）

| 名前 (Name)              | 色 (Colour)            | 食べ物 (Food)    |
|--------------------------|------------------------|------------------|
| オズワルド (Oswald)      | 黒 (Black)             | ミルク (Milk)    |
| ヘンダーソン (Henderson) | 茶トラ (Ginger)        | カリカリ (Chips) |
| クエンティン (Quentin)   | トラ (Tabby and white) | カレー (Curry)   |

<details><summary>解答（クリックして表示）</summary><div class="solution">

これはオブジェクトを定義する文法に慣れるための指の運動にすぎません。下記コードのような解答が得られているはずです。

```scala
object Oswald {
  val colour: String = "Black"
  val food: String = "Milk"
}

object Henderson {
  val colour: String = "Ginger"
  val food: String = "Chips"
}

object Quentin {
  val colour: String = "Tabby and white"
  val food: String = "Curry"
}
```

</div></details>


#### スクウェア・ダンス！

`calc` と呼ばれるオブジェクトを定義します。それは、`square` という `Double` を引数として受け取る、あなたが予想するとおり入力を2乗 (square) するメソッドを伴います。そして、計算の一部として **`square` メソッドの呼び出し** を含む `cube` と呼ばれる、入力を3乗 (cube) するメソッドを追加してください。

<details><summary>解答（クリックして表示）</summary><div class="solution">

これが解答です。`cube(x)` は `square(x)` を呼び出し、その値を `x` によってもう一度乗算します。各メソッドの結果型はコンパイラーによって `Double` として推論されます。

```scala
object calc {
  def square(x: Double) = x * x
  def cube(x: Double) = x * square(x)
}
```
</div></details>

#### 精密なスクウェア・ダンス！

前の演習から `calc` をコピー＆ペーストして、`Int` と同様に `Double` でも動作するよう一般化された `calc2` を作成してください。Java の経験を持っていれば、これはかなり簡単にできるはずです。そうでなければ、下記の解答を読んでください。

<details><summary>解答（クリックして表示）</summary><div class="solution">

Java のように Scala は特に `Int` と `Double` の間でうまく一般化できるわけではありません。しかしながら、引数の型ごとに `square` メソッドと `cube` メソッドを定義することで**オーバーロード (overload)** することができます。

```scala
object calc2 {
  def square(value: Double) = value * value
  def cube(value: Double) = value * square(value)

  def square(value: Int) = value * value
  def cube(value: Int) = value * square(value)
}
```

「オーバーロードされた」メソッドとは、異なる引数型で複数回定義したメソッドのことです。オーバーロードされたメソッド型を呼び出すたびに、Scala は引数の型を見ることによって、どの変種が必要かを自動的に判断します。

```scala
calc2.square(1.0) // `square` の `Double` 版を呼び出す
// res11: Double = 1.0

calc2.square(1)   // `square` の `Int` 版を呼び出す
// res12: Int = 1
```

Scala コンパイラーは、低い精度から高い精度が必要な場合に、数値型間の自動変換を挿入できます。例えば、`calc.square(2)` と書けば、コンパイラーは `calc.square` の唯一のバージョンが `Double` を受け取ると判断し、本当のところは `calc.square(2.toDouble)` という意図であると自動的に推論します。

高い精度から低い精度への逆方向の変換は、丸め誤差につながる可能性があるため、自動的には処理されません。例えば、下記のコードは、`x` が `Int` であり、その本体の式が `Double` であるため、コンパイルされません！（実際に試してみてください。）

```scala
val x: Int = calc.square(2) // コンパイルエラー
// <console>:13: error: type mismatch;
//  found   : Double
//  required: Int
//        val x: Int = calc.square(2) // コンパイルエラー
//                                ^
```

これは、`Double` の `toInt` メソッドを手動で使用することで回避できます。

```scala
val x: Int = calc.square(2).toInt // toInt は切り捨て
// x: Int = 4
```

---

#### :warning: 文字列連結の危険性

Java と似た振る舞いを維持するために、Scala もまた必要に応じて任意のオブジェクトを自動的に `String` に変換します。これは、`println("a" + 1)` のようなものを簡単に書けるようにするためで、Scala は `println("a" + 1.toString)` に自動的に書き換えます。

文字列連結と数値加算が同じ `+` メソッドを共有しているという事実が、予期せぬバグを引き起こすことがあるので注意しましょう！

---

</div></details>

#### 評価の順番

コンソールで入力したとき、下記プログラムの出力は何で、最終的な式の型と値は何になるでしょうか？各フィールドやメソッドの型や依存関係、評価の振る舞いをよく考えてみてください。

```scala
object argh {
  def a = {
    println("a")
    1
  }

  val b = {
    println("b")
    a + 2
  }

  def c = {
    println("c")
    a
    b + "c"
  }
}
```

```scala
argh.c + argh.b + argh.a
```

<details><summary>解答（クリックして表示）</summary><div class="solution">

これが解答です。

```scala
argh.c + argh.b + argh.a
// b
// a
// c
// a
// a
// res13: String = 3c31
```

評価の完全な順番は下記のとおりです。

```
- プログラムの最後にあるメインの合計を計算するには、
  - `argh` を読み込み、
    - `argh` のすべてのフィールドを計算するので、
      - `b` を計算すると、
        - `"b"` を印字し、
        - `a + 2` を評価するので、
          - `a` を呼び出し、
            - `"a"` を印字し、
            - `1` を返却し、
          - `1 + 2` を返却し、
        - `b` に値 `3` を格納し、
  - `argh.c` を呼び出し、
    - `"c"` を印字し、
    - `a` を評価し、
      - `"a"` を印字し、
      - `1` を返却するのですが、それは破棄され、
    - `b + "c"` を評価し、
      - `b` から値 `3` を取得し、
        - 値 `"c"` を取得し、
        - `+` を評価し、それが実際のところ文字列の連結を参照していると判断し、
          `3` を `"3"` に変換し、
        - 文字列 `"3c"` を返却し、
  - `argh.b` を呼び出し,
    - `b` から値 `3` を取得し、
  - 最初の `+` を評価し、それが実際のところ文字列の連結を参照していると判断し、
    `"3c3"` を生成し、
  - `argh.a` を呼び出し、
    - `"a"` を印字し、
    - `1` を返却し、
  - 最初の `+` を評価し、それが実際のところ文字列の連結を参照していると判断し、
    `"3c31"` を生成する
```

ふぅ、こんな簡単なコードにしてはたくさんありますね。

</div></details>

#### やぁ、人間

`person` というオブジェクトを定義します。それは、`firstName` と `lastName` というフィールドを含みます。`alien` という2番目のオブジェクトを定義します。それは、引数として `person` を受け取り、その `firstName` を使用して挨拶する `greet` というメソッドを含みます。

`greet` メソッドの型は何でしょうか？このメソッドを使用して他のオブジェクトに挨拶することはできますか？

<details><summary>解答（クリックして表示）</summary><div class="solution">

```scala
object person {
  val firstName = "Dave"
  val lastName = "Gurnell"
}

object alien {
  def greet(p: person.type) =
    "Greetings, " + p.firstName + " " + p.lastName
}
```

```scala
alien.greet(person)
// res15: String = Greetings, Dave Gurnell
```

`greet` の引数 `p` の型 `person.type` に注目してください。これは、先ほど言及した**シングルトン型 (singleton type)** のひとつです。この場合は `person` オブジェクトに固有の型なので、他のオブジェクトで `greet` を使用することはできません。これは、Scala のすべての整数で共有されている `Int` のような型とは大きく異なります。

これでは、Scala でプログラムを書く能力に大きな制限を課してしまいます。組み込み型か独自に作成した単一のオブジェクトで動作するメソッドしか書けないのです。有用なプログラムを構築するために、**独自の型を定義**し、それぞれの型で多様な値を生成する機能が必要です。クラス (`class`) を使用してこれを実現できるのですが、それは次節で扱います。
</div></details>

#### メソッドの真価

メソッドは値ですか？式ですか？なぜそうなるのでしょうか？

<details><summary>解答（クリックして表示）</summary><div class="solution">

まず、メソッドと式の等価性を扱いましょう。すでに知っているように、式は値を生成するプログラムの断片です。何かが式であるかどうかの簡単なテストは、それをフィールドに代入できるかどうかを確認することです。

```scala
object calculator {
  def square(x: Int) = x * x
}
```

```scala
val someField = calculator.square
// <console>:15: error: missing argument list for method square in object calculator
// Unapplied methods are only converted to functions when a function type is expected.
// You can make this conversion explicit by writing `square _` or `square(_)` instead of `square`.
//        val someField = calculator.square
//                                   ^
```

このエラーメッセージをまだ完全に理解はできません（「部分適用関数 (partially applied function)」については後ほど学びます。）が、`square` が**式ではない**ことを示しています。しかしながら、`square` の**呼び出し**は値を生成**する**のです。

```scala
val someField = calculator.square(2)
// someField: Int = 4
```

引数を持たないメソッドは異なる振る舞いをしているように見えます。しかしながら、これは文法のトリックです。

```scala
object clock {
  def time = System.currentTimeMillis
}
```

```scala
val now = clock.time
// now: Long = 1586352189787
```

`clock.time` を値として `now` に割り当てているように見えるにも関わらず、実際にそれは **`clock.time` の呼び出しによって返された値**を代入しています。これは、もう一度メソッドを呼び出すことで実証できます。

```scala
val aBitLaterThanNow = clock.time
// aBitLaterThanNow: Long = 1586352189933
```

上で見たように、Scala では「フィールドへの参照」と「引数のないメソッド呼び出し」は同じように見えます。これは、他のコードに影響を与えることなく、フィールドの実装をメソッドに置き換えることができる（逆も然り）ように設計されています。それは、**[統一アクセス原理 (uniform access principle)](http://en.wikipedia.org/wiki/Uniform_access_principle)** と呼ばれるプログラミング言語の機能です。

つまり、要約すると、**メソッド呼び出しは式である**が**メソッド自体は式ではない**ということです。Scala は**関数 (function)** と呼ばれる概念を持っており、それはメソッドのように呼び出せるオブジェクトです。オブジェクトが値であることをすでに知っているように、関数は値であり、データとして取り扱うことができます。お気付きのとおり、関数は**関数型プログラミング (functional programming)** の重要な部分であり、Scala の大きな強みのひとつです。関数と関数型プログラミングについては少しずつ学んでいきましょう。
</div></details>

## メソッドの書き方

前節では、メソッドの文法について見てきました。本書の主な目的のひとつは、文法を超えて、Scala プログラムを構築するための体系的な方法を提供することです。本節はそのような問題を扱う最初の節です。本節では、体系的にメソッドを構築する方法を見ていきます。Scala の経験を積んでいくうちに、この方法のいくつかの段階を省略することができますが、本書の中ではこの方法に従うことを**強く**推奨します。

アドバイスを具体的にするために、前節の演習を例として使用していきましょう。

**`calc` と呼ばれるオブジェクトを定義します。それは、`square` という `Double` を引数として受け取る、あなたが予想するとおり入力を2乗 (square) するメソッドを伴います。そして、計算の一部として `square` メソッドの呼び出しを含む `cube` と呼ばれる、入力を3乗 (cube) するメソッドを追加してください。**

### 入力と出力を特定する

最初の段階は、入力となる引数がもしあれば、その型とメソッドの結果型を特定することです。

多くの場合、演習では型を教えてくれるので、説明文からそのまま読み取ることができます。上の例で、入力型は `Double` になっています。結果型もまた `Double` になることが推論できます。

### テストケースを準備する

型だけでは物語のすべてを語れません。`Double` から `Double` への関数はたくさんありますが、2乗を実行しているものは少数です。そのため、メソッドの期待される振る舞いを例証するいくつかのテストケースを準備しましょう。

外部依存を避けたいので、本書ではテストライブラリを使用しないことにします。Scala が提供する `assert` 関数を使用することで手軽なテストライブラリを実装できます。`square` の例については、下記のようなテストケースが考えられます。

```scala
assert(square(2.0) == 4.0)
assert(square(3.0) == 9.0)
assert(square(-2.0) == 4.0)
```

### 宣言を書く

型とテストケースが準備できたので、メソッド宣言を書くことができます。その本体はまだ書けないので、その場所に Scala の便利な機能である `???` を使用しておきます。

```scala
def square(in: Double): Double =
  ???
```

この段階は、前の段階で収集した情報から機械的に与えられるべきです。

### コードを実行する

コードを実行し、それがコンパイルされていること（つまり、タイプミスをしていないこと）と、また、テストが失敗すること（つまり、何らかのテストが実行されていること）を確認してください。なお、メソッド宣言の後にテストを配置する必要があるかもしれません。

### 本体を書く

メソッドの本体を書く準備が整いました。本書を通じて、いくつかのテクニックを修得していきます。現時点では、2つのテクニックを見ていきましょう。

#### 結果型を考える

最初のテクニックは、結果型を見ることです。この場合は `Double` です。どうやって `Double` の値を生成するのでしょうか？リテラルを書くこともできますが、この場合は明らかに正しくありません。`Double` を生成する他の方法は、何らかのオブジェクトのメソッドを呼び出すことで、それは次のテクニックがもたらします。

#### 入力型を考える

次のテクニックは、メソッドの入力引数の型を見ることです。この場合は `Double` です。`Double` を生成する必要があることは確立していますが、入力から `Double` を生成するためにはどのようなメソッドを呼び出せばいいのでしょうか？そのようなメソッドはたくさんありますが、ここで呼び出すべき正しいメソッドとして `*` を選択するためにはドメイン知識を活用しなければなりません。

完全なメソッドは下記のように書くことができます。

```scala
def square(in: Double): Double =
  in * in
```

### コードを再実行する

最後に、コードを再実行して、テストがすべて通過することを確認します。

これはとても単純な例でしたが、今のプロセスを実践することで、今後遭遇するであろうより複雑な例にうまく対応できるようになります。

---

#### :information_source: メソッドを書く方法

体系的にメソッドを書くための6段階の方法があります。

1. メソッドの入力型と出力型を特定する。
2. 入力例を与えられたメソッドの期待される出力について、いくつかのテストケースを書く。これらのケースを書き出すために `assert` 関数を使用することができる。
3. 下記のようにメソッドの本体に `???` を使用してメソッドの宣言を書く。

```scala
def name(parameter: type, ...): resultType =
 ???
```
4. コードを実行し、テストケースが実際に失敗することを確認する。
5. メソッドの本体を書く。現在のところ、ここで2つのテクニックを適用することができる。
   - 結果型とそのインスタンスをどのように生成できるかを考える
   - 入力型とそれを結果型に変化させるために呼び出せるメソッドを考える
6. コードを再実行し、テストケースが通過することを確認する。

---

## 複合式

これで Scala の基本的な入門編はほぼ終了しました。本節では、より複雑なプログラムで必要になるであろう、**条件式 (conditional)** と **ブロック (block)** という2種類の特別な式について見ていきます。

### 条件式

条件式は、ある条件にもとづいて評価する式を選択することを可能にします。例えば、2つの数値のうちどちらが小さいかにもとづいて文字列を選択することができます。

```scala
if(1 < 2) "Yes" else "No"
// res0: String = Yes
```

---

#### :information_source: 条件式は式である

Scala における `if` の記述は Java と同じ構文を持ちます。重要な違いのひとつは、**Scala の条件式は式である**ということで、それは型と返却値を持ちます。

---

選択されない式は評価されません。これは、副作用を伴う式を使用すると明らかです。

```scala
if(1 < 2) println("Yes") else println("No")
// Yes
```

`No` がコンソールに出力されないので、`println("No")` という式は評価されていないことがわかります。

---

#### :information_source: 条件式文法

条件式のための文法は、

```scala
if(condition)
  trueExpression
else
  falseExpression
```

です。ここで、

- `condition` は `Boolean` 型の式
- `trueExpression` は `condition` が `true` に評価されるときに評価される式
- `falseExpression` は `condition` が `false` に評価されるときに評価される式

とします。

---

### ブロック

ブロックは、計算をまとめて並べることができる式のことです。それは、セミコロンもしくは改行によって区切られた部分式を含む中括弧のペアとして書かれます。

```scala
{ 1; 2; 3 }
// <console>:13: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
//        { 1; 2; 3 }
//          ^
// <console>:13: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
//        { 1; 2; 3 }
//             ^
// error: No warnings can be incurred under -Xfatal-warnings.
```

ご覧のように、このコードを実行すると、コンソールはいくつかの警告を発生させ、`Int` 値 `3` を返します。

ブロックは、中括弧によって囲まれた一連の式や宣言のことです。ブロックもまた式であり、各部分式を順番に実行し、最後の式の値を返します。

`1` と `2` の値を捨ててしまうなら、なぜそれらを実行するのでしょうか？これはいい質問で、上記で Scala コンパイラーが警告を発生させた理由にもなります。

ブロックを使用するひとつの理由は、最終的な値を計算する前に副作用を生成するコードを使用したいからです。

```scala
{
  println("This is a side-effect")
  println("This is a side-effect as well")
  3
}
// This is a side-effect
// This is a side-effect as well
// res3: Int = 3
```

また、下記のように中間結果に名前をつけたいときにブロックを使用することもできます。

```scala
def name: String = {
  val title = "Professor"
  val name = "Funkenstein"
  title + " " + name
}
```

```scala
name
// res4: String = Professor Funkenstein
```

---

#### :information_source: ブロック式文法

ブロック式の文法は、

```scala
{
   declarationOrExpression ...
   expression
}
```

です。ここで、

- `declarationOrExpression` は宣言か式（オプション）
- `expression` はブロック式の型と値を決定する式

とします。

---

### 覚えておいてほしいこと

条件式は `Boolean` の条件にもとづいて評価する式を選択することを可能にします。その文法は下記のとおりです。

```scala
if(condition)
  trueExpression
else
  falseExpression
```

式である条件式は、型を持ち、オブジェクトに評価されます。


ブロックは、式や宣言を順番に並べることを可能にします。それは、副作用を伴う式を順番に並べたり、計算における中間結果に名前をつけたりしたいときによく使用されます。その文法は下記のとおりです。

```scala
{
   declarationOrExpression ...
   expression
}
```

ブロックの型と値は、ブロックにおける最後の式になります。


### 演習

#### 模範的なライバル関係

下記の条件式における型と値は何ですか？

```scala
if(1 > 2) "alien" else "predator"
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
それは、値 `"predator"` を伴う `String` です。明らかにプレデターは最高です。

```scala
if(1 > 2) "alien" else "predator"
// res6: String = predator
```

型は **then** 式と **else** 式における型の上限境界によって決まります。この場合、両式は `String` なので、その結果もまた `String` になります。

値は実行時に決まります。`2` は `1` より大きいので、条件式は **else** 式の値を評価します。
</div></details>

#### あまり知られていないライバル関係

この条件式はどうでしょうか？

```scala
if(1 > 2) "alien" else 2001
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
それは値 `2001` を伴う `Any` です。

```scala
if(1 > 2) "alien" else 2001
// res8: Any = 2001
```

これは前の演習と似ていますが、その違いは結果型です。先ほど、型は真偽両式の**上限境界 (upper bound)** であることを見ました。`"alien"` と `2001` は全く異なる型なので、最も近い共通の祖先は、すべての Scala 型における最高位の基底型 `Any` になります。

これは、型がプログラムを実行する前のコンパイル時に決まるという重要な観測結果です。コンパイラーはプログラムを実行する前に `1` と `2` のどちらが大きいかを知らないので、条件式の結果型から最良の推量をするしかないのです。前の演習では `String` に至るまでの道のりを得ることができましたが、このプログラムでは `Any` が限りなく近いものになっています。

`Any` については以降の節で詳しく説明します。なお、それは `Int` や `Boolean` のような値型を包含するので、Java プログラマーは `Object` と混同してはいけません。
</div></details>

#### else のない if

この条件式はどうでしょうか？

```scala
if(false) "hello"
```

<details><summary>解答（クリックして表示）</summary><div class="solution">
結果の型と値はそれぞれ `Any` と `()` です。

```scala
if(false) "hello"
// res10: Any = ()
```

すべてのコードが等しくあるべきですが、`else` 式のない条件式の半数のみ値に評価されます。Scala は、`else` への分岐が評価されるべき場合に `Unit` 値を返すことでこの問題を回避しています。これらの式はたいてい副作用がある場合にのみ使用します。
</div></details>

## まとめ

本章では、Scala の基礎をとても簡単に紹介しました。

* 値に評価される式
* 値に名前を与える宣言

たくさんのオブジェクトについてリテラルで書く方法や、既存のオブジェクトから新しいオブジェクトを生成するためにメソッド呼び出しや複合式を使用する方法を見てきました。

また、独自のオブジェクトを宣言し、メソッドやフィールドを構築しました。

次章では、新しい種類の宣言であるクラスが、どのようにオブジェクトを生成するためのテンプレートを提供するのかを見ていきます。クラスは、コードを再利用したり、共通の型で類似のオブジェクトを統一したりすることを可能にします。