（Rの）プロミス問題　その１。


いきます。

## 遅延評価

突然ですが、Rは遅延評価な言語です。

```R
> f <- function(x) {invisible(NULL)}
> f(print(1))
```

関数の引数に渡されたもの（`x`）は、それが使われない限り評価されません。

```R
> f <- function(x) {force(x); invisible(NULL)}
> f(print(1))
[1] 1
```

使われると評価されます。

遅延評価は関数外でも使われます。

```R
> delayedAssign("x", {print("evaluated"); 1})
> x
[1] "evaluated"
[1] 1
```

`delayedAssign`は遅延評価用の代入です。この場合、`x`が評価されない限り、`x`の中身は評価されません。

```R
> x <- {print("evaluated"); 1}
[1] "evaluated"
> x
[1] 1
```

普通は代入即評価です。

## パッケージ内の変数・関数も遅延評価

普段は気づきませんが、`library(package)`とかすると、パッケージの変数にアクセスできるようになります。ただし、この段階ではR様は変数名、関数名をリストアップするだけで、実際に変数、関数の評価はされません。`lazyLoading`という仕組みです。その変数・関数にアクセスした時に初めて、内容がメモリ上に展開されます。

## 遅延評価による混乱

ほぼFAQですが、以下の例で質問をよく見ます。

```R
> f <- function(a) function() a # 関数を返す関数
> r <- list()
> for (i in 1:3) r[[i]] <- f(i)
> print(r[[1]]())
[1] 3 # 現在のiの値
> print(r[[3]]())
[1] 3 
```

`f`は関数を返す関数で、その関数は`r[[i]] <- f(i)`の段階では評価されていません。
`print(r[[1]]())`のときに初めて、`function() a`の`a`が評価されます。

さて、環境の話を思い出して欲しいんですが、`r[[i]]`つまり`function() a`の環境は`f()`の呼び出し時に作られた環境です。なので、`r[[1]]`と`r[[2]]`の環境は異なります。

```R
> environment(r[[1]])
<environment: 0x11b01e310>
> environment(r[[2]])
<environment: 0x11b012588>
```

この環境に`a`の中にあるんでしょうか？

```R
> ls(environment(r[[1]]))
[1] "a"
```

あります。ではこの`a`の値は何でしょうか？

```R
> get("a", environment(r[[1]]))
[1] 3
```

`3`です。

## もうちょっと色々な例を上げておきます

```R
> f <- function(a) function() a # 関数を返す関数
> r <- list()
> for (i in 1:3) {r[[i]] <- f(i); print(r[[i]]())} #評価もする
[1] 1
[1] 2
[1] 3
> print(r[[1]]())
[1] 1 # ちゃんと1になってる
> print(r[[3]]())
[1] 3
```

代入の直後に一回関数を評価（`r[[i]]()`）しておくと、`i`が`3`になった後でもちゃんと`1`が帰ってきます。

```R
> f <- function(a) function() a # 関数を返す関数
> r <- list()
> for (i in 1:3) {r[[i]] <- f(i)}
> print(r[[1]]())
[1] 3
> print(r[[3]]())
[1] 3
> i <- 5 # iの値を変更
> print(r[[1]]())
[1] 3 # r[[1]]は影響を受けない
> print(r[[2]]())
[1] 5 # r[[2]]は影響を受ける
```

上の例の場合、`i`の値が変わっている前に`r[[1]]`は一度評価されているので影響を受けません。
`r[[2]]`は`i <- 5`の段階で見評価なので、影響を受けます。

## クロージャの話

```R
> f <- function(a) function() a
> m <- f(1)
> m
function() a
<environment: 0x1264f9008>
```

の`f`の呼び出しで帰ってくる関数`m`はクロージャと言われます。実際のところ、Rではすべての関数はクロージャですが、上の例は明示的にクロージャっぽいのでクロージャと言われます。

上の例では、クロージャの環境は`f()`呼び出し時に動的に作られた環境です。

```R
> f <- function(a) {print(environment()); function() a} #環境を表示して、クロージャを返す
> m <- f(1)
<environment: 0x1233e2208> # これと
> environment(m)
<environment: 0x1233e2208> # これ同じ
```

もちろん、もう一回呼び出したら違う環境が作られます。

```R
> f <- function(a) {print(environment()); function() a}
> m <- f(1)
<environment: 0x1233e0898> # さっきと違う。
> environment(m)
<environment: 0x1233e0898>
```

## クロージャ作成時の値を使う正しい方法。

上の例でクロージャの環境内の変数`a`はクロージャ作成時には評価されていません。
なので、問題を解決するためにはクロージャ作成時にクロージャの環境内で`a`を評価してあげればいい、ということになります。

```R
> f <- function(a) {
+ 	force(a) # aを強制的に評価
+ 	function() a # クロージャを返す
+ }
> r <- list()
> for (i in 1:3) {r[[i]] <- f(i)}
> print(r[[1]]())
[1] 1
> print(r[[3]]())
[1] 3
```

という具合です。

`force`というのは引数を強制的に評価する関数なんですが、その実装は

```R
> force
function (x) 
x
<bytecode: 0x121195f58>
<environment: namespace:base>
```

です。別に`force`じゃなくても、一旦クロージャの環境で値を評価すれば、何を使っても大丈夫です。クロージャ作成の後でも大丈夫です。

```R
> f <- function(a) {
+ 	z <- function() a # クロージャを作る
+  force(a) # aを強制的に評価
+  z # クロージャを返す
+ }
> r <- list()
> for (i in 1:3) {r[[i]] <- f(i)}
> print(r[[1]]())
[1] 1
> print(r[[3]]())
[1] 3
```

ただまあ、最初に`force`しておく、というのが正式な方法だと思います。

## 何が起こってるのか？

次回はpromiseの説明をします。

つづく。