Swiftでは関数はファーストクラスである。一体どういうことです？


## 関数は型を持つ

関数が型を持つ？  
関数型ってやつ？
関数型言語ってやつ？
そうなの？  

よくわかりませんが、型を持つらしいです。

後で書きますが、Swiftでは関数がファーストクラスであり、
それはつまり、関数の引数や戻り値に **関数そのもの** を指定できるということです。  

Swiftは静的型付け言語です。
関数の引数や戻り値に関数を指定できるのであれば、 静的型付け言語では当然それは型を持つ必要がある。
関数が型を持てばこそ、静的型付け言語でも関数がファーストクラスとして振る舞える。

まあこれはなんか論理的に納得できるような気がします。

### 関数の型って何すか？  

関数の型は、その引数と戻り値によって決まります。

例えば以下の関数があったとき、その型は `(Int, Int) -> Int` と示すことができます。

```text
func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
```

以下はまた別の関数ですが、その型は上のやつと同じで `(Int, Int) -> Int` ですね。

```text
func multiplyTwoInts(a: Int, b: Int) -> Int {
    return a * b
}
```

上記した2つの関数 `addTwoInts` と `multiplyTwoInts` が `(Int, Int) -> Int` 型を持つなら、
これはもしや `(Int, Int) -> Int` 型の変数(とか定数とか)に代入できるんじゃないでしょうか？

```text
// addTwoIntsを代入してみる
var mathFunction: (Int, Int) -> Int = addTwoInts
println(mathFunction(2, 3)) //=> 結果は『5』

// multiplyTwoIntsを代入してみる
mathFunction = multiplyTwoInts
println(mathFunction(2, 3)) //=> 結果は『6』
```

できました！  

ここでちゃんと理解しておかないといけないのは、代入している `addTwoInts` や `multiplyTwoInts` ってやつらは、
**関数の実行結果ではなく関数そのもの** であることです。

だから、`mathFunction(2, 3)` のような形で実行できます。

### じゃあ、引数とか戻り値の無い関数の型はどうなるんすか？

引数や戻り値がない関数、例えばこんなやつです。

```text
func printHelloWorld() {
    println("hello, world")
}
```

この関数の型は、そのまま「引数なし、戻り値なし」を示す `() -> ()` が型になります。

```text
let printFunction: () -> () = printHelloWorld
printFunction()
```

簡単ですね。

_実際には、上記したような関数は引数や戻り値を持っていないのではなく、_
_Void型の引数を持っている、という方が正確である。_
_したがって、型を以下のようにして書くこともできた。_

```text
let printFunction: Void -> Void = printHelloWorld
printFunction()
```

これで、関数の型、ってやつが大体分かりました。

## 引数に関数をとる関数

何度もいいますが、Swift では関数がファーストクラスの型です。  
**ファーストクラスの型** というのは「The Swift Programming Guide」では以下のように説明されています。

- 関数は別の関数を戻り値として返すことができる
- 関数はその引数に別の関数をとることができる

いわゆる高階関数というやつですね。
「関数の型」をちゃんと理解していれば、特に難しいことは何もなく、そのまま、普通の関数の記法のルールにしたがうだけです。  

まずは、引数に関数をとる関数です。

さっきの `addTwoInts` 関数の定義をまた使います。  

```text
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5) // => "Result: 8” と表示する
```

`printMathResult` の引数は3つありますね。

- `mathFunction: (Int, Int) -> Int`
- `a: Int`
- `b: Int`

1つ目の引数が、`(Int, Int) -> Int` 型の関数であることがわかると思います。
なので、`printMathResult` 関数内でその引数の関数を実行できています。
全然難しくないですね。

## 戻り値で関数を返す関数

これも、「関数の型」が分かっていればそのまま書くだけです。

まず、以下のような2つの関数があります。

```text
func stepForward(input: Int) -> Int {
    return input + 1
}

func stepBackward(input: Int) -> Int {
    return input - 1
}
```

どちらも関数の型は、`(Int) -> Int` ですね。

じゃあ、それらの関数を返す別の関数を定義して使ってみましょう。  

```text
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)

```

`chooseStepFunction` 関数の戻り値は `(Int) -> Int` 型の関数になってます。
なので、その型をもった `stepForward` や `stepBackward` 関数を戻り値に指定できます。  

ここでも、戻り値は **関数の実行結果ではなく関数そのもの** であることをちゃんと理解しておいてください。

### ネストされた関数

関数を戻り値で返す場合、その関数内でネストされた関数を定義して返すことができます。  

```text
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
```

が、これはクロージャの説明に回します。
説明の機会があるかは不明です！

ぶっちゃけこのへん、Swift の新しい考え方というわけではなく、Objective-C でも SEL型とかブロックとかあったわけで、
そのあたり使いこなしてた人にとっては今更な話だったりすると思います。
とはいえSwiftでかなり使いやすくなっているので、やっと普通に自分でも使えるような気がしませんか。