クロージャ

自分流の定義をする前に、本来の定義を確認するのが先じゃないでしょうか、ということで。
まず、クロージャという言葉がLispやその他の関数型言語の世界で、静的スコープやファーストクラスの関数オブジェクトで静的スコープを実現するための技術を指す言葉として使われています。
Scheme : R5RSには、closureという言葉は出現しないようだ。
Scheme:番外 : Scheme入門というサイトに説明を発見。http://www.geocities.jp/shido_takafumi/lisp/scheme9a.html
Haskell : http://www.sampou.org/haskell/report-revised-j/modules.html#sect5.5.3
Concurrent Cleanのドキュメントでは、その表現を見つけられない
ML : Wikipediaのclosureの説明の例はMLです。http://en.wikipedia.org/wiki/Closure_(computer_science)
OCamlの方では、適当なサイトを見つけられなかったのですが・・・
MinCaml : http://min-caml.sourceforge.net/tutorial-mincaml-16.htm
ちなみに、HaskellConcurrent Cleanは、副作用が許されていない(全てJavaのfinal変数のようなものと考えれば近い?)言語なので、クロージャと副作用は関連のない概念だと考えられます。
(ところで、やはりというか、思ったほど適当な資料が見つからない。Wikipediaの説明が一番適切なのだけれど、これを基準にしてしまうのはちょっと・・・)

      • -

オブジェクト指向系の言語では、そもそもクロージャという言葉ではないのでは?
私の記憶では、Smalltalkクロージャとは言わず、ブロックといっていたはず。(追記)サクサクSmalltalk―オブジェクト指向のアートとサイエンスを確認したら、ブロックのクラスはBlockClosureという名前でした。[id:sumim:20050206]に、Squeakクロージャをon/offする方法が説明されています。
Rubyクロージャという言葉ではなく、ブロックと呼ぶようです。http://www.ruby-lang.org/ja/man/?cmd=view;name=%A5%E1%A5%BD%A5%C3%A5%C9%B8%C6%A4%D3%BD%D0%A4%B7#a.a5.d6.a5.ed.a5.c3.a5.af.c9.d5.a4.ad.a5.e1.a5.bd.a5.c3.a5.c9.b8.c6.a4.d3.bd.d0.a4.b7

      • -

JavaScriptはどうかなと思ったら、クロージャという言葉の説明はなく、いきなり internal closure という言葉が出てきました。
http://www.ecma-international.org/publications/standards/Ecma-262.htm

      • -

別件ですが、クロージャは記法がどうこうという話の元ネタを見つけました。
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?Closure

2つ目の違いは、それほど形式的に定義はされていませんが、大変重要なことです。これがないと、実際に使ってられないからです。クロージャをサポートする言語は、簡単なシンタックスクロージャを定義できます。あまり重要じゃないように思えますが、私はものすごく重要なことだと信じています―― これがクロージャを自然に使えるようにするための鍵なのです。 LispSmalltalkRuby を見てください。あちこちでクロージャが使われています。他の言語のクロージャに似た機能が、こんなにも使われていますか?ローカル変数と結びつけることできるというのも、クロージャが頻繁に使われる理由のひとつでしょうが、いちばんの理由は、記法がシンプルで明快だからだと思います。

えっと、Lispラムダ式は、私の感性からは、取り立てていうほどシンプルだとは思いません。Lispの関数宣言と同じくらいです。それから、型推論を持っていない静的な型付け言語の記述と、型を記述しない言語のそれを比べるのはフェアじゃないようにも思います。そういう意味では、Javaの無名クラスがそれほど煩雑な記述になっているとはいえない気がします。(あれを煩雑というなら、静的型付け言語そのものが否定されると思うので)

      • -

ところで、Rubyのブロックは、Schemeのそれのようにファーストクラスの関数オブジェクトになりえるんでしょうか? Ruby関数プログラミングに挑戦している次のサイトには、以下のような注釈がついていました。
http://sky.zero.ad.jp/~zaa54437/programming/ruby/part6.htm

注意 : Rubyの関数オブジェクトは、どうやら「関数」オブジェクトではないそうです。つまり、proc(lambda)で作ることのできるオブジェクトとは、(Smalltalk的な)ブロックであるらしく、|x,y|と引数を指定しても、それは仮引数ではなく、ブロック外の同名の変数(つまり、ブロック外のx,yという名の変数)を上書きしてしまうのだそうです。従って、これを使用してはファーストクラスの関数を表現できないことになります。ですので、Rubyでファーストクラスの関数を表現し得るかという議論は、この点からは否定されることとなるのではないかと思います。ただ、変更されるならばまた別です。

追記)最後の部分は、あまり考えないで投稿したので、なんかよく分からない文章になってますね。
ブロックパラメータがローカル環境を汚すというのは、いまいち謎仕様な感じがしますが、それがファーストクラスと関係するかというと、関係ないように思いますので、上の引用は引用元の勘違いかと思います。
ところで、(引用とはいえ)ファーストクラスのようなミーハーな言葉を使ってしまった以上、定義を付けておきます。
http://sky.zero.ad.jp/~zaa54437/programming/concepts/によれば、以下の能力を持つ言語要素のことを指します。

1.オブジェクトに名前がつけられる。
2.引数として関数・手続に渡すことができる。
3.結果値として関数から帰って来ることができる。
4.データ構造に組み込むことができる。

関数がファーストクラスということは、関数を整数や文字列となんら変わりない扱われ方をする(つまり、整数や文字列が書けるところには、関数も書ける)ということを意味しています。

      • -

それはそうと、Rubyのメソッド定義のネストは、ローカル関数ではないという説明を発見して、衝撃を受けています。
http://www.ruby-lang.org/ja/man/?cmd=view;name=%A5%AF%A5%E9%A5%B9%A1%BF%A5%E1%A5%BD%A5%C3%A5%C9%A4%CE%C4%EA%B5%C1#footmark-2
それではスコープがおかしいでしょ、というのが感想なのですが、そういえば、Perl方面で、
http://pugs.blogs.com/pugs/2006/01/todays_releasea.html

sub f ($x) {
    sub g { $x }
}
g();     # undef -- pad not initialized
my $g = f(10);
$g();    # 10 -- sub{$x} is returned at runtime
g();     # 10 -- also &g is rebound
f(20);
$g();   # 10 -- the old closure is kept around
g();     # 20 -- the new rebound &g takes the new $x

という恐ろしい仕様に "perlish" といって喜んでいる人がいたなぁ・・・