一年の計はエイプリルフールにあり?

一年の計はたいてい1月1日にたてる(と言うのかな)モノらしいのですが、
たいていその計はかなわないことが多く、悔し涙を流されることなく忘れ去られる結果となるのが自分の常orz。
であるならば、
どうせ忘れされる計であるならば、
いったこと、宣言したこと、話したこと、契約したこと(これはまずい!)を半ば反故にしてもいいとされる4月1日、エイプリルフールにおいて、一年の計をたててあげれば、たてられた計がたとえ忘れ去られたとしても、「ああエイプリルフールだったからまあいいか」って笑って許してくれるに違いないのです。


というわけで、今年の一年の計を、一年がすでに3ヶ月経過した4月1日、エイプリルフールにたててみることにしました。
一年の計は、あまり抽象的でなく、具体的で、かつ趣味的なものがいいかなと思います。
で、さらに形になれば御の字。
こんなのにしました。

1 JavaScriptカーネルシンタックス、セマンティクスを一から勉強する。
2 ウェブブラウザのためのJavaScriptウェブブラウザライブラリとJavaScriptカーネルを明確に分けることを意識する。
3 その上で、ブラウザベース、クライアントベースのJavaScriptアプリをなにかくんでみる。
4 もしかしたら今はやりのWebAPIを利用したアプリも何か作ってみるかも。
5 3、4で作るアプリの目的は、今は考えない。どんなモノを作れば楽しいのか考える。

こんなところ。
「いまさら」JavaScriptですよ。
これまでも何度か本を買って読んでそれなりに組んだり、JavaScriptコードを吐き出すコードをなぜかVBAで(泣き)組んだりもしました。
でも、結局JavaScriptの本質は未だにわかっていません。
最近ウェブを徘徊していると、JavaScriptの本来持っている、つまりJavaScriptカーネルの機能を利用したプログラムを見かけるようになってきました。
とあるウェブに載っていたJavaScriptのコードは、私をJavaScriptを本気で勉強しようと思わせる物でした。
たしかこんなやつ。

window.undefined=window.undefined;

new function() {
 var b=....;
 :
}

最初のコードは、ブラウザによっては、window.undefinedが定義されていない場合があるので、これを定義するための物、との解説がありました。
でも、window.undefinedを定義するのに、定義されていないはずのwindow.undefinedを参照して代入するとは、これ如何に?
Schemeではdefineされていない変数を参照したときには即エラー、プログラムは止まりますが、JavaScriptはもしかして止まらないで"undefined"オブジェクトかなにかそういったものが返すんじゃないかと推測しました(もしかしてbooleanのfalseじゃないよね)。
とすると、変数名タイプミスと言った良くあるバグの修正がちょっと難しいかなと思ったりすると同時に、変数のdefineはただただ代入左辺に変数名を書いてあげればいいのか、ともおもったり。
なにより、未定義の変数を利用してその変数を定義するコードを書く、というのは、それが本当にそうあるべきかは別にして、本当に単純に面白いと思ったわけです。
それから2つ目のコードです。JavaScriptのfunction文によって生成された無名関数は、私の中ではSchemeのlambda文で生成されるクロージャと等価だよね、っておもっています。
だから、2つ目のコードはただ無名関数を生成して終わりで、変数への束縛などなく終了しているので、いったい何の意味があるんだろう、っておもったんです。
そしたら、function文の前に、"new"があるじゃないですか!
以下の推測には誤りがあると思いますが、
これは多分、生成されたクロージャというか無名関数をその場で適用している、
そしてそのクロージャというか無名関数は使い捨てにしているのではないかと思いました。
なぜそんなことをするかというと、
Schemeクロージャの即時適用を考えれば納得できるのですが、
グローバル変数環境を汚染しないで、
つまり局所変数のみ定義し、グローバル変数環境では局所変数の定義をしないようにしている、
かつ、普通だったら自分で書くスタートアップルーチンに書くようなコードを、グローバル領域で書き、本当にその場で走らせる必要があるために、そんなことをしたのではないかと思います。

たしかに、JavaScriptにおける「普通だったら自分で書くスタートアップルーチン」は、たいていwindow.onloadにフックさせるとかするのかなと思いますが、window.onloadより前に行わせたいコードもあって、そういう場合は、たいていグローバル領域に直に書いてしまうのですが、それだとグローバル変数環境を汚染してしまいます。
とするならば、
グローバル領域に局所変数環境を作り出し、
その環境の中でコードを書けば、
グローバル変数領域を汚染せずに、
グローバル環境でコードを走らせることができます。
そのために、
無名関数を作り出し、即時適用し、GCされることを信じて捨てる、
というのは非常にスマートだなぁと感心しました。
Schemeで書けばこんな感じかな?)

((lambda (b) ....) ...)

(let ((b ...))
 :
)

1つ目のコードはSchemeカーネルで書いたもの、
2つ目のコードは素直にlet文をグローバル領域で利用したものです。
Schemeのlet文を利用した方が、なんか素直ですねぇ。
こう考えると、先のJavaScriptのコードは

function () {
 var b=...
 :
}();

とfunction文の最後に();を加えて、無名関数を即時適用するという風に書いていいような気がしますが、
これはもうCの世界ですね(Cでは関数を無名で生成することはできないはずですよね確か)。

void f() {
 :
}
void main(void) {
 (void* c)(void);
  c=f;
  (*c)();
}

こんな感じ。
cの変数宣言が違うと思うけど、いいや。(*c)();じゃなくc();でもいいはずだけど、いいや。
でももしかしたら、Javascirptでは、無名関数の即時適用でいきなり()をつけたりしてはいけないシンタックスになっているのかもしれず、そのために、new functionなんて書いているのかもしれません。
いずれにしろ、面白いコードに巡り会ってしまったので、javascriptをちょっと本気で勉強するのも面白いと思ってしまったわけです。
で結果としてクライアントベースのアプリが何かかければと。
ファイルの入出力はできないはずだし、自分でサーバをたててサーバーサイドのプログラムをするのもjavascriptのお勉強という趣旨からはずれるしそもそもそんな余裕もないので、どこかの面白そうなWebAPIでXML交換するのも楽しそう。
あくまで、JavaScriptプログラム言語の本質をお勉強するのが今年の目標です。
結果としてできるクライアントアプリは完全にお遊び。そんなスタンスでいきたいと思います。
ま、エイプリルフールですしね。
風呂敷を広げたって、気ぶんは軽いです。

※4/1 19:35追記
W-ZERO3esから投稿してほうったらかしにしていたら、スーパーpre記法内でHTMLのコメントアウトを使ったところ、見事に表示されていませんでしたorz。
ということで、スーパーpre記法内でHTMLのコメントアウトを外しました。あーびっくりした。