null安全でない言語は、もはやレガシー言語だ

この数年で **_null 安全_** [^99] は一気に浸透したように思います。ざっと思いつくだけでも、次のプログラミング言語で _null 安全_ が採用されました。

| 言語 | _null 安全_ に関する公式の記述 | リプレース対象言語 | オンラインドキュメント | ブラウザ上で試す |
|:--|:--|:--|:--|:--|
| [Ceylon](https://ceylon-lang.org/) | [Typesafe null and flow-sensitive typing](https://ceylon-lang.org/documentation/1.2/introduction/#typesafe_null_and_flow_sensitive_typing) | Java | [Tour of Ceylon](https://ceylon-lang.org/documentation/1.3/tour/) | [Ceylon Web IDE](http://try.ceylon-lang.org/) |
| [Crystal](https://crystal-lang.org/) | [Null Pointer Exception](https://crystal-lang.org/2013/07/13/null-pointer-exception.html) | Ruby | [Crystal Programming Language](https://crystal-lang.org/docs/index.html) | [play.crystal-lang.org](https://play.crystal-lang.org/) |
| [Flow](https://flowtype.org/) | [Maybe Types](https://flowtype.org/docs/nullable-types.html) | JavaScript | [Quick Reference](https://flowtype.org/docs/quick-reference.html) | [Try Flow](https://flowtype.org/try/) |
| [Hack](http://hacklang.org/) | [Nullable](https://docs.hhvm.com/hack/types/type-system#nullable) | PHP | [Hack Documentation](https://docs.hhvm.com/hack/) | - |
| [Kotlin](https://kotlinlang.org/) | [Null Safety](https://kotlinlang.org/docs/reference/null-safety.html) | Java | [Reference](https://kotlinlang.org/docs/reference/basic-syntax.html) | [Try Kotlin](http://try.kotlinlang.org/) |
| [Python](https://www.python.org/) | [Union types](https://www.python.org/dev/peps/pep-0484/#union-types) | - | [The Python Tutorial](https://docs.python.org/3/tutorial/index.html) | [Interactive Shell](https://www.python.org/shell/) |
| [Rust](https://www.rust-lang.org/) | [Module std::option](https://doc.rust-lang.org/1.7.0/std/option/index.html) | C++ | [The Rust Programming Language](https://doc.rust-lang.org/book/) | [Rust Playground](https://play.rust-lang.org/) |
| [Swift](https://swift.org/) | [Optionals](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID330) | Objective-C | [The Swift Programming Language](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/) | [IBM Swift Sandbox](https://swiftlang.ng.bluemix.net/#/repl) |
| [TypeScript](https://www.typescriptlang.org/) | [Non-nullable Types](https://blogs.msdn.microsoft.com/typescript/2016/09/22/announcing-typescript-2-0/#user-content-non-nullable-types) | JavaScript | [Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) | [Playground](http://www.typescriptlang.org/play/) |

これらは、表中の「リプレース対象言語」に挙げたように、多くのメジャー言語に対する代替手段でもあります。 Java の代わりには Kotlin や Ceylon が、 JavaScript には TypeScript や Flow が、 Objective-C には Swift が、そして PHP には Hack があります。 Python は自身に _null 安全_ を取り込みました。 Crystal は直接 Ruby と連携して使えるわけではありませんが、 Ruby 風の _null 安全_ な言語です。 Rust は C++ の代替を目指して開発され、 Firefox の一部で C++ のコードを置き換えるのに使われています [^100] 。

`null` が引き起こしてきた数々の問題を考えると、僕は、 _null 安全_ は GC （やその他の安全なメモリ管理手法）に匹敵するプログラミング言語の進化だと考えています。僕はこれまで 10 年以上に渡って C や Java, JavaScript, Objective-C, Python などの _null 安全_ **でない** 言語を使ってきました。しかし、この 2 年間ちょっとの間、仕事で _null 安全_ な言語を使うようになって、もはやそれなしのコーディングは考えられないと感じています。もし、まだ _null 安全_ を体験したことがないなら、それは体験する価値のあるものだと強くオススメします。

_null 安全_ 自体は特に新しい考え方ではありません。しかし、どれだけ優れた仕組みが存在しても、実務で使える言語に採用されなければ多くの人がその恩恵を受けることはできません。 _null 安全_ が様々な言語に採用されることで、今、ようやく _null 安全_ な言語を選択肢として考えられる状況になってきました。

かつて、「テストのないコードはレガシーコードだ」 [^101] という言葉で、テストの必要性が訴えられました。今では、テストが大事だという考えはプログラマの間でほぼ共通認識となっています。同じように、少し気が早くても、あえて **_null 安全_ でない言語はレガシー言語だ** と言い切ることで、 _null 安全_ の普及を加速させることができるんじゃないでしょうか。

本投稿では、 _null 安全_ の普及を目的とし、 _null 安全_ について **言語横断的に** まとめました。

- null 安全とは何か
- null 安全だと何がうれしいか
- nullable を快適に扱うための仕組み
- nullable の種類と特徴
- 言語別雑感
- null 安全な言語の始め方
- FAQ

## null 安全とは何か

_null 安全_ とは、一言で言えば、 `null` （ `nil`, `None` など）が原因で実行時エラーにならない仕組みです。

`null` に対してメソッドコールやメンバアクセスすると多くの言語では実行時エラーとなります。

```java
// Java
String s = null;
s.length(); // java.lang.NullPointerException
```

```js
// JavaScript
let s = null;
s.length; // TypeError: Cannot read property 'length' of null
```

```python
# Python
s = None
len(s) # TypeError: object of type 'NoneType' has no len()
```

一方、 **_null 安全_ な言語では実行時ではなくコンパイル時（動的型付言語では静的解析時）にエラーとなります**。プログラムが実行できないので、当然ながら `null` が原因で実行時エラーになることはありません。実行するためにはコードを修正する必要があります。

```kotlin
// Kotlin
val s: String? = null
s.length // error: only safe (?.) or non-null asserted (!!.) calls are allow
```

```ts
// TypeScript
let s: string|null = null;
s.length; // Object is possibly 'null'.
```

```python
# Python
s = None # type: Optional[str]
len(s) # error: Argument 1 to "len" has incompatible type "Optional[str]"; expected "Sized"
```

上記の `String?` や `string|null`, `Optional[str]` が重要な点です。この `?` や `|null`, `Optional` はこの変数 `s` が `null` かもしれない（ **_nullable_** である）ことを表しています。 `null` には `length` というメンバはないので、 `s.length` はコンパイルエラーを起こし、コードを修正するよう要求されているわけです。

では、どうやって `s` の長さを取得すればいいのでしょうか。 `s` が `null` でないことをチェックすれば OK です。

```kotlin
// Kotlin
val s: String? = null
if (s != null) {
    s.length // OK
}
```

```ts
// TypeScript
let s: string|null = null;
if (s != null) {
    s.length; // OK
}
```

```python
# Python
s = None # type: Optional[str]
if s is not None:
    len(s) # OK
```

この `if` の `{}` の中では `s` が `null` でないことが確定しており、そのため `s.length` がエラーになりません。コンパイラが制御フローを解析し、 `{}` の中では `s` は `String?` ではなく `String` だと判断してくれるのです。

では、変数宣言時に `?` や `|null`, `Optional` を付けると `null` チェックが必須になるのなら、それらを付けずにいきなり `null` を代入してみたらどうなるでしょうか。

```kotlin
// Kotlin
val s: String = null // error: null can not be a value of a non-null type kotlin.String
s.length
```

```ts
// TypeScript
let s: string = null; // Type 'null' is not assignable to type 'string'.
s.length;
```

```python
# Python
s = None # type: str
# error: Incompatible types in assignment (expression has type None, variable has type "str")
len(s)
```

この場合は代入がコンパイルエラーになります。 _null 安全_ な言語では、 `?` や `|null`, `Optional` が付いていない型（ **_non-null_** [^102] ）の変数に `null` を代入することはできません。そのため、 _non-null_ な変数の値は `null` でないことが保証されています。上記の `s.length` も `null` が原因で実行時エラーになることはありません。

このように _nullable_ と _non-null_ を型で区別し、 `null` による実行時エラーを防止する仕組みが _null 安全_ です。

## null 安全だと何がうれしいか

プログラマはコードを書き、それをコンパイル（または静的解析）し、実行します。実行できるプログラムはテストされ、出荷され、ユーザーが利用します。この工程の中で、 **問題は早めに発見されることが好ましい** です。もし、実行時エラーをテストで検出できなければ、それはそのまま潜在バグとして製品に組み込まれ、出荷されてしまいます。コンパイルエラーであれば開発時に **必ず** 気付くことができます。

**経験上、コードのロジック自体が間違えていたというケースを除けば、 `null` は最もよくあるバグの原因の一つだと思います。その問題をコンパイル時に排除できるのは素晴らしいことです。**

`null` の生みの親である Tony Hoare は次のように述べています [^103] 。

> それは10億ドルにも相当する私の誤りだ。null参照を発明したのは1965年のことだった。（中略）これは後に数え切れない過ち、脆弱性、システムクラッシュを引き起こし、過去40年間で10億ドル相当の苦痛と損害を引き起こしたとみられる。

`null` の発明から半世紀を経て、ようやく僕らは _null 安全_ によって `null` の苦しみから解放されようとしているのです。

### null 安全は生産性も高める

いくら安全になるとはいえ、 `null` チェックを強制する _null 安全_ は一見煩わしく、生産性を下げるものに見えるかもしれません。しかし、 **_null 安全_ は安全性を高めると同時に生産性も高めます**。

_null 安全_ では、 `Foo?` などで表される _nullable_ が目立ちますが _non-null_ も重要です。 `null` が代入されることのない変数や `null` を許容しない引数、 `null` を返さない関数の戻り値などはすべて _non-null_ にできます。 _null 安全_ **でない** 言語では値が `null` でないことを `assert` やテストで確認しなければなりません。 _non-null_ を使えば、それらがなくてもコンパイラが `null` でないことを保証してくれます。しかも実行時ではなくコンパイル時にです。

_nullable_ に対して書かなければならない `null` チェックは、 _null 安全_ **でない** 言語でも必要なものです。余分な `null` チェック が増えているわけではありません。

つまり、 _null 安全_ は

- _non-null_ によって不要なコードを省略できる
- _nullable_ によってエラーを早め（コンパイル時）に検出できる

ことによって、安全性だけでなく生産性も高める仕組みなのです。

## nullable を快適に扱うための仕組み

_null 安全_ なコードを快適に書くためには、 _nullable_ を快適に扱える必要があります。基本的に _nullable_ な値は `null` チェックによって処理されるわけですが、 `null` チェックだけで対処するには面倒なケースもあります。 _null 安全_ な言語の多くには、そのようなケースで _nullable_ な値を扱うための便利な仕組みが備わっています。本節ではそのような仕組みの内、次のものを取り上げ説明します。

- `null` チェックに伴うキャスト
- `!`, `!!`
- `?.`, `?->`
- `?:`, `??`
- `map`
- `flatMap`
- `do` 記法
- `?`
- 型推論

`null` チェックが煩わしいと感じるなら、道具を上手く使えていないのかもしれません。本節を読むことでそのような問題が解決する可能性があります。もしくは、あなたの言語に「快適に書くための仕組み」が足りていないのかもしれません。「快適に書くための仕組み」の充実度は言語によって大きく異なります。次の表は、どの言語にどの道具があるかをまとめた表です。「快適に書くための仕組み」の中には関数で実装できるようなものもあるので、他の言語の「仕組み」を眺めて自分の言語に取り入れられないか考えてみて下さい。

| 言語 | `!`, `!!` | `?.`, `?->` | `?:`, `??` | `map` | `flatMap` | `do` 記法 | `?` | 型推論 |
|:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| Ceylon |  | ◯ | ◯ |  |  |  | ◯ | ◯ |
| Crystal |  |  |  |  |  |  |  | ◯ |
| Flow |  |  |  |  |  |  | ◯ | ◯ |
| Hack |  | ◯ |  |  |  |  | ◯ | ◯ |
| Haskell | ◯ |  | ◯ | ◯ | ◯ | ◯ |  | ◯ |
| Java | ◯ |  | ◯ | ◯ | ◯ |  |  | △ |
| Kotlin | ◯ | ◯ | ◯ | ◯ | ◯ |  | ◯ | ◯ |
| Python |  |  |  |  |  |  | △ | ◯ |
| Rust | ◯ |  | ◯ | ◯ | ◯ |  |  | ◯ |
| Scala | ◯ |  | ◯ | ◯ | ◯ | ◯ |  | ◯ |
| Swift | ◯ | ◯ | ◯ | ◯ | ◯ |  | ◯ | ◯ |
| TypeScript | ◯ |  |  |  |  |  |  | ◯ |

- Java と Scala は _null 安全_ な言語ではありませんが、 `null` を使わずに `Optional`, `Option` を使って _null 安全_ なコードを書くことができます。そのため、 `Optional`, `Option` でどの道具を使えるかを示すために表に加えています。
- Python の `?` が △ なのは、 `Union[Foo, None]` を `Optional[Foo]` と表すシンタックスシュガーはあるけれども、 `Foo?` ほど簡潔でないからです。
- Java の型推論が △ なのは、ラムダ式の型は推論できるけれども変数の型は推論できないからです。

### `null` チェックに伴うキャスト

これまでに見てきたように、 `if` 文で `null` チェックをすると、その `if` 文の `{}` の中では `String?` が `String` として扱われる（キャストされる）という仕組みがありました。この仕組みは **_スマートキャスト (Smart cast)_** (Kotlin), **_制御フロー解析 (Control flow analysis)_** (TypeScript), **_Flow-sensitive typing_** (Ceylon) などと呼ばれています。以下、本投稿では _スマートキャスト_ と呼びます。

_スマートキャスト_ がないと、 `null` チェックをしても `s` は `String?` のままです。 `s` が `String?` のままだと、 `null` チェックをしても結局 `s.length` でコンパイルエラーになってしまいます。 `length` にアクセスするには `s` を強制的に `String` にキャストしなければなりません。

```kotlin
// Kotlin
val s: String? = null
if (s != null) {
  (s as String).length // String にキャストしてから s を使う
}
```

しかし、これだともし `null` チェックを忘れてもコンパイルが通ってしまいます。

```kotlin
// Kotlin
val s: String? = null
(s as String).length // 実行時エラー
```

`s` は `null` なので、上記のコードは `String` にキャストしようとしたときに実行時エラーになります。 _nullable_ と _non-null_ によって、せっかくコンパイル時に `null` によるエラーを検出できるようになったのに、これでは意味がありません。

このように、 `null` チェックと _non-null_ へのキャストが独立していると、キャストの失敗によるエラーが実行時に発生します。 **`null` チェックと _non-null_ へのキャストをセットで行う仕組みは _null 安全_ を実現する上で欠かせまぜん**。

似たような仕組みとして、 Swift や Rust には `if let` (**_Optional binding_**) が、 Java の `Optional` には `ifPresent` メソッドがあります。 Haskell や Scala では **_パターンマッチング_** を使います。どれも _スマートキャスト_ とは異なる仕組みですが、やりたいことは `null` チェックの条件分岐と _non-null_ へのキャストという意味では同じです。

### `!`, `!!`

どうしても `null` である可能性を無視して _nullable_ を _non-null_ に変換したいこともあります。

例として、テキストフィールドに入力された文字列を整数に変換する処理を考えましょう。一般的に、文字列から整数への変換は失敗する可能性があります。 `"123"` は `123` に変換できますが `"ABC"` は整数に変換できません。変換に失敗した場合には `null` を返すとすると、文字列を整数に変換する処理は `String` から `Int?` への変換だと考えられます。

```swift
// Swift
let number: Int? = Int(text)
```

しかし、テキストフィールドに制約が加えられていて数字しか入力できないこともあります。そのようなケースでは文字列から整数への変換に失敗することはありません。それでも、テキストフィールドから得られるのは文字列なので、型の上では整数への変換が必要となります。

```swift
// Swift
if let number: Int = number { // null チェック
  // ここでは number を Int として使える
}
```

必ず `null` でないとわかっている場合にも、 `null` チェックを書かなければならないのは手間です。 **型は万能ではありません。ロジックの上では `null` にならないけれど、型の上では _nullable_ になってしまうことがしばしばあります**。このままでは、 _null 安全_ **でない** 言語では書かなくて良かった無駄な `null` チェックを書かなくてはならないことになり、生産性が下がりかねません。 **`null` である可能性を明示的に無視して _nullable_ を _non-null_ に変換する簡単な方法が必要です。**

Swift では _nullable_ な値の後ろに `!` という後置演算子を付けることで、強制的に  _non-null_ に変換することができます。これを **_Forced unwrapping_** と呼びます。

```swift
// Swift
let number: Int = Int(text)!
```

`number` の型が `Int?` ではなく `Int` であることに注意して下さい。これは、 `!` によって `Int?` 型である `Int(text)` の戻り値が `Int` 型に強制変換されたからです。

もし、値が `null` のときに `!` で _non-null_ に変換しようとすると実行時エラーとなります。 `!` を乱用してはいけません。上記の例のように **絶対に `null` にならないけれども型の上では _nullable_ になってしまうケースや、使い捨てのスクリプトで `null` ならクラッシュしても良いケースなど、 `!` が問題を引き起こさないよう常に意識的でなければなりません**。

安全でない操作には長い名前を付けるべきだという意見もありますが、僕はその意見には反対です。補完があれば長くても簡単に入力できます。そして、 **`!` はたった 1 文字ですが、プログラマが明示的に書く必要があります。** `!` を書くときに立ち止まって、本当に問題ないケースか確認するという作業を怠らなければ _null 安全_ を破壊することはありません。

TypeScript の `!` や Kotlin の `!!` も同じように _nullable_ を _non-null_ 化する後置演算子です。 Java の `Optional` クラスや Scala の `Option` クラスには同じ目的の `get` メソッドが、 Rust の `Option` には `unwrap` メソッドがあります。それらを適切に使うことで、快適に _null 安全_ なコードを書くことができます。

余談ですが、 Swift では _Forced unwrapping_ 以外にも `!` という記号は危険な処理に用いられることが一貫されており、 `!` を書くときに常に意識的でいやすいです。対して、例えば Java では `get` というメソッドが安全な処理（ `Map` の `get` メソッド等）でも使われており、 Swift と比較すると危険な処理であることを意識しづらいのではないかと思います。ロジカルには二つのやっていることは同じですが、視覚的・感覚的に訴えることのできる Swift のような言語デザインは素晴らしいと思います。

### `?.`, `?->`

_nullable_ な値のメンバやメソッドにアクセスしたい、ただし、値が `null` の場合は結果も `null` でいいというのもよくあるケースです。愚直に書くと次のようになります [^104] 。

```kotlin
// Kotlin
val s: String? = null
val length: Int?
if (s != null) {
  length = s.length
} else {
  length = null
}
```

`length` を取得するためだけにこの分岐を書くのは大変です。 Swift や Kotlin, Ceylon, Hack などの `?.` （ Swift では **_Optional chaining_** と呼びます）を使えばこれを簡単に実現できます（ Hack では `.` の代わりに `->` を使うので `?->` です）。

```kotlin
// Kotlin
val s: String? = null
val length: Int? = s?.length // s が null なら結果も null
```

**特に、 `?.` は `null` になるかもしれない操作をチェーンするときに重宝します。**

```kotlin
// Kotlin
val baz: Baz? = foo?.bar?.baz
```

これを `null` チェックと条件分岐で書こうとすると次のようになります。

```kotlin
// Kotlin
val baz: Baz?
if (foo != null) {
  val bar: Bar? = foo.bar
  if (bar != null) {
    baz = bar.baz
  } else {
    baz = null
  }
} else {
  baz = null
}
```

`?.` によって、 `null` チェックによる複雑な条件分岐を書かかずに簡潔なコードで済ませられます。

### `?:`, `??`

`null` の場合にデフォルト値を与えたいというのもよくあるケースです。

```kotlin
// Kotlin
val s: String? = null
val length: Int
if (s != null) {
  length = s.length
} else {
  length = 0 // デフォルト値 0 を与える
}
```

Kotlin の `?:` 演算子や Swift の `??` 演算子を使えばこれを簡単に書けます。

```kotlin
// Kotlin
val s: String? = null
val length: Int = s?.length ?: 0 // デフォルト値 0 を与える
```

Java の `Optional` の `orElse` メソッドも同様の働きをします。

### `map`

`?.` は強力な構文ですが、 _nullable_ な値を演算子のオペランドにしたり、関数やメソッドの引数に渡したいときには役に立ちません。

たとえば、 `Int?` を二乗することを考えてみましょう。 `?.` と同じように元の値が `null` のときは結果として `null` を得たいとします。

もし、 `square` （二乗する）というメソッドがあれば次のように書けます。

```swift
// Swift
let number: Int? = nil
let squared: Int? = number?.square()
```

しかし `*` 演算子で `number * number` のように書こうとすると `?.` ではうまく書けません。

```swift
// Swift
let number: Int? = nil
let squared: Int? = number?. * number?. // コンパイルエラー
```

これを `null` チェックと条件分岐で書くと次のようになります。

```swift
// Swift
let number: Int? = nil
let squared: Int?
if let number: Int = number { // null (nil) チェック
  squared = number * number
} else {
  squared = null
}
```

とても面倒です。こういう場合には、 `map` という高階メソッドが役立ちます。

```swift
// Swift
let number: Int? = nil
let squared: Int? = number.map { $0 * $0 }
```

Swift を知らないと `number.map { $0 * $0 }` という表記が何を表しているのかわかりづらいと思いますが、これは JavaScript の `number.map(function(x) { return x * x; })` または `number.map(x => x * x)` 、 Java の `number.map(x -> x * x)` に相当します。

`map` メソッドに渡されたラムダ式は、 `Optional` の値が `nil` でない場合だけ実行され、 `map` の結果として返されます。ラムダ式の引数に渡されるのは _non-null_ 化された値です。もし `Optional` の値が `nil` であれば結果も `nil` になります。

Java の `Optional` や Scala, Rust の `Option` の `map` メソッド、 Haskell の `Maybe` の `fmap` も同様の挙動をします。 Kotlin では _nullable_ に `map` メソッドはないですが、 `?.` と `let` メソッドを組み合わせることで `number?.let { it * it }` と書くことができます。

### `flatMap`

前述の文字列から整数への変換

> ```swift
// Swift
let number: Int? = Int(text)
```

の `text` が `String` ではなく `String?`だったらどうでしょうか。整数への変換が `Int?` を返すので、 `map` で書くと `Optional` がネストして戻り値の型が `Int??` になってしまいます。

```swift
// Swift
let text: String? = nil
let number: Int?? = text.map { Int($0) }
```

`Int??` がネストしている部分です。今ほしいのは `Int?` なのでこのままではダメです。

`flatMap` は `map` と似ていますが、ネストした `Optional` を一重に潰して（フラットにして）返してくれます。

```swift
// Swift
let text: String? = null
let number: Int? = text.flatMap { Int($0) }
```

Java の `Optional` や Scala の `Option` の `flatMap` メソッド、 Rust の `Option` の `and_then` 、 Haskell の `Maybe` の `>>=` 演算子も同様の挙動をします。

**実は `map` と `flatMap` があれば `?.` でできることはすべてできます。 `?.` は `map` と `flatMap` をより簡単に書くための表記だと言えるでしょう。 `map` と `flatMap` は `?.` ではカバーできないケースに対応可能なより柔軟な仕組みとして重要です。**

なお、 Kotlin や Ceylon, TypeScript, Python では _nullable_ をネストすることができません。詳しくは後述しますが、たとえば Kotlin の `Int??` は `Int?` と等価になります。そのため、これらの言語では `map` と `flatMap` が等価になります。 Kotlin では `flatMap` 相当のことをするのにも、 `map` と同じく `?.let` で代替できます。

### `do` 記法

`a: Int?` と `b: Int?` があったときに、 `a` と `b` を足すにはどうすればいいでしょうか。例によって、 `a` か `b` のどちらかが `null` だった場合は結果として `null` を得たいとします。

`null` チェックをして条件分岐は面倒なので、 `flatMap` と `map` を使って書いてみます。

```swift
// Swift
let a: Int? = 2
let b: Int? = 3
let sum: Int? = a.flatMap { x in b.map { y in x + y } }
```

`a.flatMap { x in b.map { y in x + y } }` は、 JavaScript なら `a.flatMap(x => b.map(y => x + y))` 、 Java なら `a.flatMap(x -> b.map(y -> x + y))` という意味です。

書けないことはないですが、ラムダ式をネストするのは少々読みづらいです。 Haskell では `do` 記法を使い、より簡潔に記述できます。

`do` 記法は `flatMap` のネストを簡潔に書くための記法です。 `map` が混ざっていてはいけないので、まずは `map` を `flatMap` で書き変えてみましょう。

```swift
// Swift
let sum: Int? = a.flatMap { x in b.flatMap { y in .some(x + y) } }
```

`.some(x + y)` は、 `Int` 型である `x + y` の結果を `Optional` で包んで `Int?` 型にするための処理です。これを Haskell で書くと次のようになります。

```haskell
-- Haskell
sum = a >>= (\x -> b >>= (\y -> Just (x + y)))
```

`>>=` は Swift の `flatMap` に、 `Just` は `.some` に当たります。 `do` 記法を使うと、このコードを次のように書き変えられます。 `do` 記法は `>>=` のシンタックスシュガーなので、この二つのコードは等価です。

```haskell
-- Haskell
sum = do
  x <- a
  y <- b
  return (x + y)
```

`<-` は `do` 記法で用いられ、上記のコードでは　_nullable_ な `a`, `b` を _non-null_ な `x`, `y` に変換しています。 _non-null_ に変換さえできれば最後に `x + y` を計算するだけです。 `>>=` （ `flatMap` ）をネストするよりずっとわかりやすいと思います。

Scala にも同様の仕組みがあります。

```scala
// Scala
val a = Option(2)
val b = Option(3)

val sum = for {
  x <- a
  y <- b
} yield x + y
```

これまでの関係をまとめると、

- 多くのケースで簡潔な `?.` を使う
- 一部のケースでは `?.` では書けないので、上位互換の `map` や `flatMap` を使う
- `flatMap` がネストするとわかりづらいので `do` 記法を使う

となります。ただし、これは言語横断的な話で、 Haskell や Scala に `?.` はないですし、 Swift や Kotlin には `do` 記法がありません。実用上はその言語で欠けている部分を諦めて別の方法で妥協する必要があります。

### `?`

Swift や Kotlin, Ceylon, Hack, Flow などの言語では、型名に `?` を付けて _nullable_ な型を表します。 _nullable_ な型を書く機会は多いので、簡潔な記法が用意されているのはうれしいところです。

`Foo?` は、 Swift では `Optional<Foo>` の、 Ceylon では `Foo|Null` のシンタックスシュガーです。 Kotlin のように `?` が直接的に _nullable_ であることを表す言語仕様なら `?` の存在は必須ですが、そうでなくても `?` がシンタックスシュガーとして用意されていれば便利です。

TypeScript には、残念ながら 2.0 時点でこのようなシンタックスシュガーはありません。 Crystal にもありませんが、 Crystal のように極力コード中に型を書かず推論させる言語であれば不要だと思います。

### 型推論

直接的に _null 安全_ に関わっているわけではないですが、僕は **_型推論_** も _null 安全_ を快適にするために重要だと考えています。

_null 安全_ は、 `null` に関するエラーを型を使ってコンパイル時（または静的解析時）に検出する仕組みです。そのため、言語に静的型付けであることを強制します。しかし、 _null 安全_ のために動的型付けの書き心地が損なわれてしまっては、 _null 安全_ を取るのか、動的型付けの書き心地を取るのかという話になってしまいます。

静的型付けでも、 _型推論_ で変数や引数、戻り値の型を書かなくてよいのであれば、動的型付けに近い書き心地を実現できます。

```swift
// Swift （型推論なし）
let numbers: [Int] = [2, 3, 5]
let squares: [Int] = numbers.map { (x: Int) -> Int in x * x }
```

```swift
// Swift （型推論あり）
let numbers = [2, 3, 5]
let squares = numbers.map { $0 * $0 }
```

```js
// JavaScript
let numbers = [2, 3, 5];
let squares = numbers.map(x => x * x);
```

静的型付けの Swift でも型推論があれば、動的型付けの JavaScript と同じような簡潔さでコードが書けているのがわかると思います。

## nullable の種類と特徴

一口に _nullable_ と言ってもその実現方法は様々です。しかし、大きく分けると二つに分けられます。それは _nullable_ な型をネストできるかできないかです。

**ネストできる**

- Haskell
- Java
- Rust
- Scala
- Swift

**ネストできない**

- Ceylon
- Crystal
- Hack
- Kotlin
- Python
- TypeScript

_nullable_ な型をネストした `Foo??` という型は何を表すのでしょうか。もし `Foo?` を単に `Foo` か `null` を入れられる型だと考えると、 `Foo??` であっても `null` を入れられるという性質を二重に記述しているだけになり `Foo?` と変わらないように思えます。

`Foo??` が何の役に立つのかは例を見てみるのが一番です。最も身近な例の一つは、 `Map` や `Dictionary` 、ハッシュを使うときです。

Kotlin や Java の `Map<K, V>` は `K` 型のキーで `V` 型の値を引くためのクラスです。キーで値を引くと、キーに対応した値が存在する場合としない場合があります。キーが存在しない場合は `null` を返したいので、戻り値の型は `V?` になります。例えば、 `Map<String, Int>` なら `String` 型のキーで値を引き、戻り値として `Int?` を得ます。

```kotlin
// Kotlin
val map: Map<String, Int> = mapOf("a" to 2, "b" to 3, "d" to 5)
map["a"] // 2
map["e"] // null （キー "e" に対応した値が存在しない）
```

では、値として `null` も格納したい場合はどうなるでしょうか。つまり、 `Int?` を `V` とし、 `Map<String, Int?>` としたいということです。このとき、キーで値を引いた戻り値の型は、 `V?` の `V` が `Int?` なので `Int??` になります。しかし、 Kotlin では `?` は `null` を代入できるかどうかを表すだけなので、 `Int??` は `Int` か `null` か `null` か、という意味になり `Int?` と同一です。その結果、

```kotlin
// Kotlin
val map: Map<String, Int?> = mapOf("a" to 2, "b" to 3, "c" to null, "d" to 5)
map["a"] // 2
map["c"] // null （キー "c" に対応した値 null ）
map["e"] // null （キー "e" に対応した値が存在しない）
```

となり、 `null` という値が返されたのか、値が存在しなかったのかを区別することができません。

もし _nullable_ な型をネストできれば話は違います。 Swift では `Int??` と `Int?` が区別され、次のようになります。

```swift
// Swift
let map: [String: Int?] = ["a": 2, "b": 3, "c": nil, "d": 5]
map["a"] // Optional(Optional(2))
map["c"] // Optional(nil)
map["e"] // nil
```

これなら、 `nil` という値が存在したのか、それとも値が存在しなかったのかで分岐することができます。

```swift
// Swift
if let c: Int? = map["c"] {
  if let c: Int = c {
    // nil でない値が存在した場合
  } else {
    // 値 nil が存在した場合
  }
} else {
  // キーに対応した値が存在しなかった場合
}
```

_nullable_ な型がネストできるということはそれだけ表現力が高いということです。ですので、僕は一般論としてはネストできる方が望ましいと考えています。ただ、パフォーマンスや言語仕様、実行環境との相性などを考慮すると、何がベストかは一概には言えません。たとえ _nullable_ な型をネストすることができなくても _null 安全_ の魅力を大きく損ねるわけではありません。たまに不便なケースがある程度です。

本節ではさらに詳しく、それぞれの言語で _nullable_ な型がどのように実現されているのか見ていきます。仕組みを知れば、なぜ _nullable_ な型をネストできる言語とできない言語があるのかも理解できると思います。

### nullable か non-null かだけを区別

一番単純な方法で、型に `?` をつけると _nullable_ に、そうでなければ _non-null_ になるという方法です。 Kotlin や Hack が採用しています。ある型 `Foo` に `?` をつけて `Foo?` とすると（ Hack では `?Foo` ）、 `Foo?` 型の変数には `Foo` インスタンスの他に `null` も代入できます。

```kotlin
// Kotlin
val s1: String = null // コンパイルエラー
val s2: String? = null // OK
```

この場合、 `Foo??` のように _nullable_ な型をネストしても、 `Foo` か `null` か `null` ということを表すだけであり、 `Foo` か `null` 、つまり `Foo?` と言っているのと同じです。そのため、 `Foo??` と `Foo?` は同じ型を表します。

_nullable_ な型をネストできないのは不便なときもありますが、 Kotlin においては妥当な選択だったんじゃないかと思います。 Kotlin は "100% interoperable with Java" を謳う Java 仮想マシン上で動作する言語です。 Java には `null` が存在し、その Java との連携を考えると、この実装は自然で理にかなっていると思います。

### Union type

Ceylon や TypeScript, Python, Crystal が採用しているのがこの方式です。これらの言語の型システムには **_Union type_** が存在しており、それを使って _nullable_ を実現しています。 _Union Type_ とは複数の型のいずれかを表す型です。たとえば、 `Foo|Bar` のようにして `Foo` または `Bar` を代入可能な型を作ります（ Python では `Union[Foo, Bar]`）。

Ceylon では `Foo|Null`, TypeScript では `Foo|null`, Python では `Union[Foo, None]` のようにして _nullable_ な型を表します。 Ceylon の `null` は `Null` 型の値、 TypeScript の `null` は `null` 型の値、 Python の `None` は `None` 型の値として扱われます。

```ceylon
// Ceylon
Foo|Null foo = null;
```

```ts
// TypeScript
let foo: Foo|null = null;
```

```python
# Python
foo = None # type: Union[Foo, None]
```

`Foo|Null` が `Foo` 型の値か `null` かを代入できるというのは自然な表現です。言語仕様として _Union type_ を持つなら、 _Union type_ で _nullable_ を表現するのは自然だと思います。

なお、 Ceylon や Python には、 `Foo|Null` や `Union[Foo, None]` をより簡潔に記述するためのシンタックスシュガーが用意されています。 Ceylon では `Foo?` は `Foo|Null` と、 Python では `Optional[Foo]` は `Union[Foo, None]` と等価です。上記のコードは次のようにも書けます。

```ceylon
// Ceylon
Foo? foo = null;
```

```python
# Python
foo = None # type: Optional[Foo]
```

TypeScript にはこのようなシンタックスシュガーはないので単純に `string|null` のようにして _nullable_ であることを表します。 Crystal にもシンタックスシュガーがないですが、前述のように、 Crystal では型を明記することがほとんどないので問題にならないと思います。

_Union type_ で _nullable_ を表す場合もネストすることはできません。  Kotlin のときと同じで、 `Foo|Null|Null` (`Foo??`) は `Foo` か `Null` か `Null` かなので、 `Foo|Null` (`Foo?`) 、つまり `Foo` か `Null` かと同一です。式変換で書くと `Foo?? == (Foo?)? == (Foo|Null)|Null == Foo|Null|Null == Foo|Null == Foo?` と書けます。

### Tagged union

Swift や Rust, Haskell が採用しているのがこの方法です。 Swift でも `Foo?` のようにして _nullable_ な型を表しますが、値を持つときは `some` 、持たないときは `none` というタグが付けられています。 _Union type_ 風に書くと、 `Foo?` が `some(Foo)|none` と表されるようなイメージです。タグ付きの _Union_ なので **_Tagged union_** と呼ばれます。

_nullable_ を表す Swift の `Optional` と Haskell の `Maybe` は次のように宣言されています。

```swift
// Swift
enum Optional<T> {
  case none
  case some(T)
}
```

```haskell
-- haskell
data Maybe a = Nothing | Just a
```

Swift では `none` と `some` が、 Haskell では `Nothing` と `Just` がタグです。

**タグがあることで _nullable_ な型をネストできるようになります。** `Foo?? == (Foo?)? == some(some(Foo)|none)|none` なので、明確に外側の `?` が `none` なのか、内側の `?` が `none` なのかを区別することができます。

_Union type_ 同様、 _Tagged union_ で _nullable_ な型を表すのも、直接的に値があるかないかを表しているので自然です。言語仕様として _Tagged union_ を持つなら、ネストでき、自然な表現である _Tagged union_ で _nullable_ な型を表すのが望ましいと思います。

### クラスや構造体

Java の `Optional` や Scala の `Option` はクラスで実現されています。

Java の `Optional` は単純にフィールドに値を保持し、それが `null` かどうかでメソッドの挙動が変化するようになっています。 Scala はおもしろくて、抽象クラス `Option` を継承した具象クラス `Some` と `None` として実装され、ポリモーフィズムで挙動が切り替わるようになっています。オブジェクト指向的には Scala の方がキレイな実装なように感じます。

Java の `Optional` の `isPresent` メソッドは次のように実装されています。

```java
// Java
public boolean isPresent() {
  return value != null;
}
```

しかし、 Scala の `Option` の `isEmpty` は `Some` と `None` でそれぞれ実装されています。

```scala
// Scala
final case class Some[+A](x: A) extends Option[A] {
  def isEmpty = false
}
case object None extends Option[Nothing] {
  def isEmpty = true
}
```

`false`, `true` を返しているだけで条件分岐はありません。ただし、 Scala がポリモーフィズムで切り分けているのは `isEmpty` だけです。 `map` や `flatMap` など、その他のメソッドは条件分岐で記述されています [^105] 。やろうと思えばすべてのメソッドの挙動をポリモーフィズムで切り替えられます [^106] が、おそらくパフォーマンス上の（条件分岐があっても静的ディスパッチした方が速いという）理由で条件分岐で書かれているのだと思います。

なお、 Java の `Optional` を Scala の `Option` のように継承でサブクラスを作れなかったのは、 Java に `sealed class` がないからだと思われます。もし、 Java で `Optional` を継承して `Some` と `None` を作ろうとすると、 `Optional` を `final` クラスにすることができないので `Some` と `None` の他にも `Optional` のサブクラスを作れてしまいます。 Scala の `sealed class` は継承を限定できるので `Some` と `None` 以外に `Option` のサブクラスを作ることはできません。

この方法であれば、 `Optional` はただのジェネリックなクラスなので `Optional<Optional<Foo>>` として問題なくネストできます。

追記: コメントで @kmizu さんに[ご指摘いただいた](http://qiita.com/koher/items/e4835bd429b88809ab33#comment-bca0e884f74ca1acdd9a)通り、 Scala や Kotlin の `sealed class` は _Tagged union_ を作る手段なので、 Scala の `Option` は _Tagged union_ とも言えます。詳しくは[コメント欄](http://qiita.com/koher/items/e4835bd429b88809ab33#comment-bca0e884f74ca1acdd9a)を御覧下さい。

## 言語別雑感

今度は言語別に _null 安全_ に関連した雑感を述べます。

- C#
- C++
- Crystal
- Go
- Java
- JavaScript
- Kotlin
- Objective-C
- Python
- Ruby
- Scala
- Swift
- TypeScript

### C# #

C# の `T?` (`Nullable<T>`) は本投稿で見てきた _nullable_ とよく似ているように見えますが、 `T` として値型しかとれないという問題があります。また、 _nullable_ な値のメンバにアクセスしてもコンパイルエラーとなりません。これが参照型に拡張され、静的に型チェックされ、参照型の `T` が _non-null_ 化されれば _null 安全_ な言語となります。

現状では中途半端で残念な仕様ですが、 C# はこれまでも先進的な仕様を取り入れてきた言語であり、また _null 安全_ になった TypeScript と同じ開発者が関わっているので、今後 _null 安全_ になることを期待しています。

追記: @gorn708 さんから補足コメントをいただきました。

> 次のC#のバージョンだとこの辺が本件の関連ですかね。
> https://github.com/dotnet/roslyn/blob/features/NullableReferenceTypes/docs/features/NullableReferenceTypes/Nullable%20reference%20types.md

この Proposal が採用されて、 C# が _null 安全_ に一歩近づくといいですね。

### C++

C++17 で `std::optional` が導入されます。しかし、それだけで _null 安全_ になるわけではありません。既存のコードベースが巨大なので、すべてが `std::optional` に対応して、 C++ が _null 安全_ になるというのは現実的ではないでしょう。そもそも、そういうことを目指している言語でもないと思うので、それでいいのかもしれませんが。

### Crystal

基本的に型を書かずに推論させるという方針は Ruby 的な言語仕様と相性が良さそうです。しかし、 Ruby と連携せずにどこまで Ruby プログラマを取り込めるかが普及するかの分かれ目になってきそうです。まだ 1.0 がリリースされていないので、今後の展開に注目です。

### Go

Go は過去 10 年で登場した人気言語の中ではめずらしく _null 安全_ **でない** 言語です。

僕は Go に詳しくないですが、 Go はこれまでのプログラミング言語の進化に逆らって、大胆に仕様を削ぎ落としてシンプルであることを目指した言語だと理解してます。ジェネリクスがなくても型付けされた配列やマップがあれば大体問題ないでしょ的な。

しかし、 Kotlin のように単に _nullable_ と _non-null_ を区別するだけであれば、言語仕様も大して複雑化しないと思うので、是非取り入れて欲しいところです。身近に Go に精通した人がいないので、 Go プログラマがどう感じているのか聞いてみたいです。

### Java

Java 8 で `Optional` が追加されましたが、 Java で _nullable_ をすべて `Optional` にしようというのは無理があります。標準ライブラリレベルで `null` を返すものがたくさんあるので、結局混ざってしまいます。例えば、 `Map` の `get` メソッドはキーに対応する値がなければ `null` を返します。 _null 安全_ な言語では _nullable_ になっているところです。また、 Java の `Optional` はフィールドに使わない方がいい [^107] という話もあり、そもそもが _null_ を代替できるものではありません。

別のアプローチとして、 JSR 305 [^108] が進めばアノテーションで _non-null_ チェックできるようになるかもしれません。標準ライブラリに片っ端から `@NonNull` をつけてくれれば大分楽になりそうです。ただ、しばらくは JSR 305 の標準化も期待できないので、サードパーティの `@NonNull` 的なものでがんばるしかないのでしょうか。たとえ `@NonNull` が標準になっても、本投稿で挙げた「快適に書くための仕組み」があるわけではないですし、辛い状況は続きそうです。

### JavaScript

型アノテーションに関する話もある [^109] [^110] [^111] ようですが、近いうちに採用される見込みはほぼなさそうです。 _null 安全_ は更にその先の話になるので、 JavaScript を _null 安全_ に書きたいなら、しばらくは TypeScript か Flow を使うのが現実的だと思います。

### Kotlin

言語自体の問題ではないですが、 Swift が Objective-C の言語仕様に手を入れることで Objective-C との連携を改善して、 Objective-C との境界でも _null 安全_ なコードを書けるようになってきているのに対して、 Kotlin と Java の境界では _null 安全_ が破壊されてしまう状況が辛いです。このあたりは、同じ組織が両言語を開発しているかどうかの差が大きそうです。前述のように Java が `@NonNull` を採用してくれれば解決するかもしれません。

### Objective-C

Objective-C はめずらしく、 `nil` に対してメソッドコールしたり、 `nil` のプロパティにアクセスしたりしてもエラーにはならない言語です。

```objc
Foo *foo = nil;
NSString *bar = foo.bar; // OK: bar == nil
```

しかし、これは _null 安全_ ということではありません。いつでも `nil` が実行時エラーを起こさないわけではなく、この `bar` を次のように使うと実行時エラーとなります。

```objc
NSURL *url = [[NSURL alloc] initWithString: bar]; // 'NSInvalidArgumentException', reason: '*** -[NSURL initWithString:relativeToURL:]: nil string parameter'
```

Objective-C の `nil` の扱いは一見安全なように見えて、問題の発覚を遅らせ、解決をより難しくしているだけです。潜在バグを生みやすいという点で、僕は Objective-C 方式は最悪だと考えています。かつて、 Objective-C で書いたプログラムを Java に移植したときに、 Java で `NullPointerException` が発生して初めて Objective-C 側の `nil` ハンドリングが不適切だったことに気付くということが何度もありました。

Swift が安定してきた今、もはや Swift を使わずに Objective-C を使う理由はほぼないように思います。 C++ 連携したいのでもない限り Swift を使いましょう。

### Python

Python の言語仕様に型ヒント [^116] が取り入れられるのは 3.5 からですが、コメント構文を使うことで Python 2 でも型ヒントを記述し _null 安全_ なコードを書くことができます。

```python
# Python 3
def to_int(s: str) -> Optional[int]:
```

```python
# Python 2
def to_int(s): # type: (str) -> Optional[int]
```

_型ヒント_ やコメント構文で記述された型は mypy [^112] [^113] を使ってチェックします。 mypy は Python の静的型チェッカーです。 Python 2 でも使える [^114] ということは、すべての Python プログラマが今すぐでも _null 安全_ なコードを書けるということです。

なお、 mypy は現状ではデフォルトで _null 安全_ なモードになっていないので、 _null 安全_ にするには

```bash
mypy --strict-optional foo.py
```

のように `--strict-optional` オプションを指定する必要があります [^115] 。

Python の `Optional` にはまだ「快適に書くための仕組み」のほとんどありません。関連する Proposal として PEP 505 [^117] がありますが、当面は「快適な仕組み」をあきらめるか、自力で関数を作って再現する必要があるでしょう。

### Ruby

静的型付 + 型推論が流行り、多くの動的型付言語も型アノテーションを取り入れる中、一向にその動きが見えなかった Ruby ですが、 RubyKaigi 2016 の Matz の講演 [^118] で静的に型推論する話が取り上げられました。これがどういうものになるかはまだわかりませんが、 _null 安全_ のためには静的型が欠かせないので歓迎です。もし、 Ruby 3 に _null 安全_ も取り入れられればうれしいですね。

### Scala

僕は Scala をほとんど触ったことがないので、 Scala で `null` がどのように扱われているのか長い間疑問だったんですが、次のツイートで疑問が解けました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">たとえば、「ScalaはnullをOptionで代替できるけど、言語仕様上はnullを使えるから結局その点はJavaと変わらない」という批判がたまにあるのだけど、純粋に言語仕様に関する批判としては正しいのだけど、「Scalaではnullを（原則）使わない」文化が醸成されていて</p>&mdash; 水島宏太（構文解析おじさん） (@kmizu) <a href="https://twitter.com/kmizu/status/782360813340286977">2016年10月1日</a></blockquote>

Scala は言語仕様的には _null 安全_ でないけれども、 `null` を使わずにすべて `Option` に統一するという文化によって _null 安全_ を実現しているようです。

### Swift

ここに挙げた言語の中では _nullable_ な型を一番快適に使える言語だと思います。「快適に書くための仕組み」が充実していることに加え、連携先の言語（ Swift の場合は Objective-C ）側を修正することで、 _null 安全_ でない Objective-C との境界でも _null 安全_ なコードを書けるようになっていることが大きいです。両方の言語を Apple が主導しているからこそできる芸当です。

### TypeScript

TypeScript 2.0 で _null 安全_ な言語に進化を遂げました。ただし、今のところデフォルトでは _null 安全_ なモードになって **いない** ので、 `--strictNullChecks` フラグをオンにする必要があります。 [^104]

_null 安全_ になったとは言うものの、今のところ Python 同様「快適に書くための仕組み」がほぼありません。例えば、 `?.` は JavaScript 待ちのようです [^119] 。将来的な発展に期待です。

## null 安全な言語の始め方

_null 安全_ な言語が良さそうに見えても、既存のコードベースやライブラリもあり、今使っている言語を変更するというのは大変な作業です。しかし、 _null 安全_ な言語の中には既存の言語とシームレスに連携して、一つのプロジェクトの中でミックスしてコードを書けるものもあります。それなら、新しく書く部分だけを _null 安全_ な言語で書き始めることもできます。

本節では、次の _null 安全_ **でない** 言語を使っている人を対象に、できるだけ簡単に _null 安全_ な言語を使い始めるための方法を述べます。

| 言語 | _null 安全_ な言語の導入しやすさ |
|:--|:-:|
| Java | ◯ |
| JavaScript | ◎ |
| Objective-C | ◯ |
| Python | ◎ |
| Ruby | △ |

ただし、マークの意味は次の通りです。

| マーク | 意味 |
|:-:|:--|
| ◎ | 既存コードに対して付加的であり、問題が起こってもすぐに元に戻すことができる。導入のための障害はほぼ存在しない。 |
| ◯ | 既存コードとシームレスに連携することができる。ただし、新しい言語で書いたコードは新しい言語としてメンテする必要はある。新しい言語は言語仕様が変化しがちなので、メンテコストは既存コードより相対的に高くなることが多い。 |
| △ | 既存のコードと連携することはできない。使い捨てのスクリプトや試験的なプロジェクトなど利用できるケースが限定的。 |

### Java

Java の既存コードと連携できて _null 安全_ なコードを書ける言語としては Ceylon, Kotlin, Scala あたりが有名です。僕は特に Kotlin をオススメします。

Kotlin は構文が Java と近く、 Java プログラマにとって違和感がなく使えると思います。 Ceylon はキーワードが特殊なのと、これからあまり流行ると思えないので微妙です。 Scala については関数型言語的な考え方など学ばなければならないことが多いと思います。

Kotlin と Java では、それぞれの言語で書かれたクラスやメソッドを互いにシームレスに利用することが出来ます。 Java で書かれたクラスをそのまま Kotlin 側で使ったり継承したりできるので、まずは新しく書くクラスだけ Kotlin で書いてみるのがいいと思います。

特に、 Android アプリ開発者であれば、 Kotlin は準公式言語のようなものです。 Android Studio は IntelliJ IDEA をベースに作られていますが、 Kotlin は IntelliJ IDEA を開発している JetBrains が作った言語です。 Android Studio 上でも Java と比べても遜色ないレベルのサポートを受けることができます。 [^120] [^121]

### JavaScript

AltJS は色々ありますが、無難に TypeScript か Flow を使うのがいいと思います。 TypeScript と Flow の使い分けは、 @mizchi さんの↓が参考になります [^122] 。

> 流行っているライブラリのみを組み合わせて使う場合や、バックエンドとの連携において型が十分に提供される環境なら、正直、flowtypeよりtypescriptでいいと思っています。flowtypeが力を発揮する環境は、既存のJSが大量に存在する環境や、railsなどの動的な型のフレームワーク環境で、静的な定義が抽出できない環境だと思います。

TypeScript も Flow も JavaScript にトランスパイルされるので、導入後何か問題が起こっても TypeScript や Flow のコードを捨てて、トランスパイル後の JavaScript コードだけ使うことができます。そのため、既存のプロジェクトに対しても導入のハードルは低いです。

なお、 TypeScript 2.0 の段階ではデフォルトで _null 安全_ なモードになっていないので注意して下さい。 _null 安全_ なモードにするには、 `--strictNullChecks` を指定する必要があります。デフォルトではないですが、常に `--strictNullChecks` をオンにすることが推奨されています。 [^104]

### Objective-C

Objective-C と連携できる _null 安全_ な言語は Swift 一択だと思います。これまでの Swift は破壊的変更が多く、メンテコストがおそろしくて Swift に移行できなかった人も多いかもしれません。しかし、現行の Swift 3 からはできるだけ後方互換が保たれる予定です。僕の勤務先では Swift バージョンアップ時のマイグレーションコストを差し引いても Swift で開発する生産性が勝つという判断でこれまでも Swift で開発してきましたが、今後はマイグレーションコストも小さくなり、ますます Objective-C を使う理由がなくなりそうです。

Swift のコードは Objective-C のコードと互いに連携することができます。 Objective-C で書かれたクラスを Swift 側で継承し、それを Objective-C 側で使うようなこともできます。すでに Objective-C のコードが存在するなら、新しく書く部分だけを Swift で書いてみるのがいいと思います。 Xcode を使っているなら、特に新しくインストールしなければならないものはありません。

### Python

mypy [^112] を導入することで今すぐにでも Python で _null 安全_ なコードを書くことができます。 Python 2 でも使える [^114] ので、今すぐ Python 3 に移行できなくても今すぐ始めることができます。 Python 2 でも使えるコメント構文は実行時にはただのコメントとして解釈され、動作に一切影響を与えないので、既存のプロジェクトにも気軽に導入できます。

mypy と Python の **_Gradual Typing_** について学ぶには次の各記事が参考になります。

- [翻訳] Python の静的型、すごい mypy! [^113]
- What is Gradual Typing: 漸進的型付けとは何か [^123]
- Mypy syntax cheat sheet [^124]
- PEP 484 -- Type Hints [^116]

前述のように、 mypy では現状デフォルトで _null 安全_ なモードになっていないので、 `--strict-optional` オプションを指定する必要があります [^115] 。

### Ruby

残念ながら、本節で挙げた他の言語ほど、 Ruby の場合はうまくいきません。 Ruby の代替である Crystal は、 Ruby と構文が似ているだけで Ruby のコードと連携することができません。既存のプロジェクトの一部だけを Crystal にするというのは難しいでしょう。

しかし、独立したスクリプトなら Crystal で書いても問題ないはずです。書けるところから Crystal を試してみるのが良いでしょう。 Amethyst [^125] という Rails ライクな Web フレームワークもあるので、小規模な新規プロジェクト等で試してみるのも良いかもしれません。

## FAQ

はてブコメントや Twitter を眺めているときちんと伝わっていないと思われることがあったので簡単に回答します。なお、僕と完全に意見が同じわけではないですが、 @omochimetaru が[同じ趣旨でより多様な質問に丁寧に回答している](http://qiita.com/omochimetaru/items/ee29d4c6eb0d78f02b15)ので、下記で足りなければそちらも御覧下さい。

### Q. null 安全がそんなに良いものならとっくに普及しているはずでは？

A. 良いものでもすぐに普及するとは限りません。今では当たり前になっている GC やオブジェクト指向やラムダ式、高階関数が多くの言語に取り入れられるまでにどれだけの時間がかかったか思い出して下さい。

### Q. null 安全を導入したらよくわかってない初心者がひどいコードを書いてより悲惨なことになるのでは？

A. この可能性は否定できないですが、この論法では新しいものは何も導入できないことになってしまいます。使いこなすのが著しく難しいものならその指摘も的外れではないですが、 _null 安全_ なコードを書く上で気を付けなければならないことはそれほど多くなく（ _nullable_ のまま値を取り回しすぎない、コンパイラを黙らせるだめに `?:` 等でテキトーに値を与えない等）、たとえばオブジェクト指向と比較しても難しくないと思います。

### Q. null オブジェクトじゃダメなの？

A. `null` オブジェクトには致命的な問題があります。それは `null` 、つまり値が存在しないときに期待される挙動は文脈によって異なるということです。例えば、[こちらのコード](https://gist.github.com/koher/43e8de7d91c4a4596eb91d3dd945ffd6)の 58 行目に渡すべき適切な `null` オブジェクトを実装することはできません。 `Integer` が存在しないときに、それが `0` として振る舞って欲しいのか、 `1` として振る舞って欲しいのかは文脈によって異なるからです。

### Q. 安全性と生産性のトレードオフでは一概に良いものと言えないのでは？

A. _null 安全_ は **安全性と生産性を同時に高めるもの** です。詳しくは[本文に追記したのでそちらを御覧下さい](http://qiita.com/koher/items/e4835bd429b88809ab33#null-%E5%AE%89%E5%85%A8%E3%81%AF%E7%94%9F%E7%94%A3%E6%80%A7%E3%82%82%E9%AB%98%E3%82%81%E3%82%8B)。

### Q. null でエラーを扱うとエラー情報を扱えず辛くない？

A. エラー情報が必要な場合には `null` でエラーを表すべきではないと思います。また、 `null` のまま取り回すとどこでエラーが発生したのかわからなくなってしまうので、エラーになる可能性のある関数が _nullable_ を返す場合には、できるだけ早い段階でエラー処理をすべきです。

### Q. Option について紹介するならモナドに触れるべきでは？

A. モナドについて詳しい人には改めて説明する必要はないと思いますし、詳しくない人に対してモナドの話まですると混乱するだけかと思い、本投稿では省略しました。

### Q. ?. があるから◯◯も null 安全では？

A. `?.` やそれに類似した仕組みを持つ言語は多いですが（そして、 _null 安全_ な言語の `?.` も Groovy や CoffeeScript, Dart などの動的型付言語由来だと思いますが）、 _null 安全_ の肝はコンパイル（静的解析）時に `null` によるエラーを検出できることなので、 `?.` だけあっても _null 安全_ にはなりません。

[^99]: _null 安全_ （または _null 安全性_ ）は _null safety_ の訳語です。 _null safety_ という用語は主に Kotlin コミュニティで使われているもので、言語によって `Optional` や `Option`, `Maybe`, _nullable type_ などの型で実現できる、 `null` が原因で実行時エラーを起こさない性質のことを表します。そのような性質を表す言葉として _null 安全_ はぴったりだと思うので、本投稿では _null 安全_ という呼び方を採用します。

[^100]: [Shipping Rust in Firefox](https://hacks.mozilla.org/2016/07/shipping-rust-in-firefox/)

[^101]: [レガシーコード改善ガイド](https://www.amazon.co.jp/dp/B01AN97W08)によるレガシーコードの定義

[^102]: _non-nullable_ と言うこともありますが（ TypeScript など）、本投稿では Kotlin 流に _non-null_ で統一しています。

[^103]: [アントニー・ホーア - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%B3%E3%83%88%E3%83%8B%E3%83%BC%E3%83%BB%E3%83%9B%E3%83%BC%E3%82%A2)

[^104]: Kotlin の `if` 文は式なのでそのまま戻り値を代入することができますが、他言語のプログラマには馴染みのない使い方なのでここでは文として使用しています。

[^105]: [Option.scala - scala/scala](https://github.com/scala/scala/blob/2.12.0/src/library/scala/Option.scala)

[^106]: [Optional.kt - qoncept/kotopt](https://github.com/qoncept/kotopt/blob/a6bfaca6a33b660d50a4c741c4de5c43bff4a32b/src/Optional.kt): Kotlin で `sealed class` を使ってポリモーフィズムで `Some` と `None` の挙動を切り替えた例

[^107]: [OptionalがSerializableではない話と使い方まとめ - きしだのはてな](http://d.hatena.ne.jp/nowokay/20150901)

[^108]: [JSR 305: Annotations for Software Defect Detection](https://jcp.org/en/jsr/detail?id=305)

[^109]: [Proposal for types in Harmony](http://wiki.ecmascript.org/doku.php?id=strawman:types)

[^110]: [Types (Experimental) - google/traceur-compiler](https://github.com/google/traceur-compiler/wiki/LanguageFeatures#types-experimental)

[^111]: [ES8 Proposal: Optional Static Typing](https://esdiscuss.org/topic/es8-proposal-optional-static-typing)

[^112]: [mypy](http://mypy-lang.org/)

[^113]: [\[翻訳\] Python の静的型、すごい mypy!](http://qiita.com/t2y/items/2a1310608da7b5c4860b)

[^114]: [mypy: Type checking Python 2 code](http://mypy.readthedocs.io/en/latest/python2.html)

[^115]: [mypy: Experimental strict optional type and None checking](http://mypy.readthedocs.io/en/latest/kinds_of_types.html#experimental-strict-optional-type-and-none-checking)

[^116]: [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)

[^117]: [PEP 505 -- None-aware operators](https://www.python.org/dev/peps/pep-0505/)

[^118]: [RubyKaigi 2016 基調講演レポート Ruby3 Typing](http://memo.goodpatch.co/2016/09/rubykaigi-2016-report-ruby3-typing/)

[^119]: [Suggestion: "safe navigation operator", i.e. x?.y 16 - Microsoft/TypeScript](https://github.com/Microsoft/TypeScript/issues/16#issuecomment-172023042)

[^120]: [Getting started with Android and Kotlin](https://kotlinlang.org/docs/tutorials/kotlin-android.html)

[^121]: [Android開発を受注したからKotlinをガッツリ使ってみたら最高だった](http://qiita.com/omochimetaru/items/98e015b0b694dd97f323)

[^122]: [型なき世界のためのflowtype入門](http://qiita.com/mizchi/items/95ee0101ac22e4b7b662)

[^123]: [What is Gradual Typing: 漸進的型付けとは何か](http://qiita.com/t2y/items/0a604384e18db0944398)

[^124]: [Mypy syntax cheat sheet](http://mypy.readthedocs.io/en/latest/cheat_sheet.html)

[^125]: [Codcore/amethyst](https://github.com/Codcore/amethyst): Crystal 版の Rails