なぜ null はそのプログラミング言語にあるのか（その1 - ”無”の無い世界）

# 前提
[TaPL](http://estore.ohmsha.co.jp/titles/978427406911P) 読みながら [Haskell/Denotational semantics](http://ja.wikibooks.org/wiki/Haskell/Denotational_semantics) 見て、自分なりに納得した己が解釈を__文芸的に__綴っていくだけの内容です

# 序： void, null, undefined, (), [], ⊥
どんな言語でも_「空っぽ」_なり_「無い」_なり_「未定義」_なりを意味する値が用意されており、型付けが動的だろうと静的だろうとこれらに対してだけはヤケに自由度の高い用法を許されています。

## Haskell の undefined と ( ) 型
Haskellであっても、以下のコードは「正しく型づけされ、正しく動作する」としてコンパイルが通ります

```hs
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib n
 | n > 1     = fib (n - 2) + fib (n - 1)
 | otherwise = undefined -- (n < 0)
```

なお、この時の `undefined` はこういう型で存在しています

```hs
undefined :: a -- どんな型であっても良い
```

ついで、Haskell には__「何も返さない事を意味する型」__として`()`(Unit型と読む)モノがあります。`main`の型が`IO ()`です。`putStrLn :: String -> IO ()`であったり、IOが関わる処理では割と頻出します

## ※この内容はあくまでも『考察』です※
javascirptのグローバル変数`undefined`,`null`、Rubyの`NilClass`、Objective-Cの`nil`、Javaの`null`…様々な言語に其々の「空」や「無」や「未定義」を意味する値が用意されていますが、そもそも何でこうした値を用意しなくてはいけなかったのか？ という点について振り返ってみます

## null とは
往々にして、各自のプログラミング遍歴で `null` に持つ_「意味」_は異なってくると思います

- `null` は__「空」/「無」__を意味する
- `null` は__「未定義値」__を意味する
- `null` は__インスタンスが無かった時のアレ__
- __`x.do(some) unless x` でブロック進んじゃってグエーってなるヤツ__
- __`==` `!` の結果でfalsyとして扱われてコーディングややこしくさせてるヤツ__

この記事の主題は**「なんで、こんなに厄介な存在が要るん？」**について、**それなりに「しょうがにゃいにゃあ」と思える解釈**を綴るものです

# 「空」/「無」/「未定義」の無い世界
はじめに、C言語で考えてみます。尤も、この手の話だったらALGOLとかCOBOLやPascalの話もしないといけないのでしょうけれど、それらへは大きく語れる知見を持ってはいないので…
## true/false ? no, it's "0 or not."
```c
extern int
doSomething()
{
   /* ... */
}

int
main()
{
    while(0) {
      /* ここは絶対に実行されない */
      doSomething();
    }
    return 0;
}
```

C言語そのものにはbool型というのが提供されておらず、条件分岐は `0` か `0`以外を真偽値として扱います。(C99からは `#include <stdbool.h>` すれば一応bool型を使えますが、それでも`if(){}`や`for(;;){}`、`while(){}`にはそのまま`int`のリテラルが使えます)

`enum` による列挙にしても、実体は整数ですし、基本的に _整数の値をどのように解釈するか_ というハンドリングが求められます。TaPL では「C言語の静的型検査の型システムは安全ではない」と述べられていますが、次に続く内容でその一端を触れる事が出来ます

## void* NULL
C言語仕様では、`malloc`でメモリ確保に失敗した時に返すヌルポインタは処理系に応じてその判断が要る為、`stdlib.h` から `NULL` を利用し、同値判定させるコトで「失敗」を判定させるのが慣習となっています
(`NULL`はC89から整数定数`0`か`(void*) 0`で表現されるものと定義されていますが、コンパイル後にどうなるかは実装依存とされています)

```c
#include <stdlib.h>

/* ... */
  int* ptr = (int*)malloc(sizeof(int) * len); 
  if (NULL == ptr) {
    exit(EXIT_FAILURE);
  }
  /* ... */
  free(ptr);
  ptr = NULL;
/* ... */
```
## int is_empty(void* ptr) への実装自由度の問題
なお、`NULL`に実値のあるオブジェクトのポインタや関数のポインタを割り当ててはいけないというのがあり、それは安心できるのですが、__「それが空っぽであるかどうか」__は、プログラマの設計に裁量が求められます

1. 構造体は__グローバル領域で宣言されているが、中身は空っぽ__
2. 構造体は__スタック領域の中で宣言されており、中身は空っぽ__
3. 構造体としての変数のポインタが`NULL`である__(ヒープ領域にアドレス確保してない)__
4. 構造体としての変数のポインタが`NULL`である__(アドレス確保に失敗した！)__
5. 変数のポインタはヒープアドレスには存在するが
   - a.メンバーのポインタは未だ`NULL`__(メンバーへの`malloc`忘れてる)__
   - b.メンバーのアドレスも確保されているが、値は未だ代入されていない
6. アドレスはまだヒープ領域から参照できるが、**単に`free()`の後に`NULL`代入するの忘れた(ヤバイ)**

この中で確実に_「不手際」_なのは 6. くらいですが、それ以外については__「ライブラリ利用者がどう介入したか？」__によって_「ヘマ」_か_「設計ミス」_か_「バグ」_か分かれます。転じて、__コードの読み手からは実態を推し量りにくい__とも言えます。

# 書き手と読み手に強いるモノ
というわけで、__言語設計上で「空」「無」を意味するモノが無い__という事は、プログラマに__「何を以ってして空とするか」を自己責任で決めさせる__事を意味します

そして、__「空」__だけでなく__「意図的に、その時点では”無い”状態である」__と、__「この時点では未定義としか言い様のないモノである(しかし宣言はしないといけない)」__ことを、__ライブラリを読み、利用する人__へも理解を要求する事になります

ライブラリのソースにコメントなどがあれば、それを確認する事で設計者の意図を組みとれる術はありますが、既にダイナミックリンクライブラリとしてバイナリ化されてしまったモノとなると困難なはずです

そこで__利用する側がコンパイル時や実行時に知る事が出来る、利用上の注意点である、メタな情報__としての__「型」と「値」__のアイデアが活きてきます

# 次回 「”無”が有る世界」
モチベーションと反響があったら続き書きます。
Lisp の `'()`, Objective-C の `nil`, RDB(SQL)の`NULL`, Python の `None` 等々の話から、__「無い」を意味する値の意味__ について

## 見識違いへのツッコミ等
ありがとうございます、ご教授願います