selflearn @ ウィキ

A Definition of Closures

最終更新:

selflearn

- view
メンバー限定 登録/ログイン

A Definition of Closures - クロージャの定義


開始日 2007年02月09日
翻訳完了日 2008年03月16日
最終更新日(ちょこちょこ直したり) 2009年06月03日

(のんびりやっていたら、1年もかかってしまった・・・)

はじめに

Martin Fowler's Bliki in Japaneseというサイトで、Closureについての和訳が載っています。この中で、

Neal Gafter がクロージャの歴史について素晴らしい投稿をしています。

という記述と共にブログの記事が紹介されていました。Closureとは何なのか、そしてClosureについてまだよく分かっていないので、勉強がてら訳してみようと思いました。
ちなみにこの方、Googleの中の人です。2008/10/3時点の情報ではMicrosoftに転職されたようです

原著


注意

  • もともと個人利用を目的として日本語化したために、けっこう意訳している部分があります。「意味分からないよ」とか「おかしいんじゃない?」とかいうのがあれば、オリジナルを参照するか、コメントで質問してください(がんばって調べます)。

また、オリジナルのサイトには30近く(2007/3/12現在)のコメントが付いています。この内容は訳していませんので、全体理解のためにはそちらも見ておくことをお勧めします。

用語

訳文に出てくる各語に対応する原文と、その意味を以下に記します。

訳語 原文 意味
関数を値とする式 function-valued expression 式を評価した値が関数になるもの
レキシカルスコープ lexical scope ブロック内で定義された変数はそのブロック内でしかアクセスできないこと。Wikipediaの説明
ダイナミックスコープ dynamic scope レキシカルスコープの定義に加え、あるブロック(サブルーチン)をコールした側のスコープにもアクセスできること。Wikipediaの説明

更新履歴

  • 2007/03/12 作成開始
  • 2008/07/01 shiro氏からコメントを受けて、内容を修正。「higher-order programming:×トップダウン式のプログラム ○高階プログラミング」「function-valued expression:×関数評価による表記法 ○関数を値とする式」とのこと。ありがとうございます。


訳文

Sunday, January 28, 2007

A Definition of Closures

クロージャとは何なのか(2007/1/28)


There has been some confusion over our proposal to add closures to the Java Programming Language. After all, doesn't Java already have closures in the form of anonymous inner classes? What is the point of adding something to the language that it already has? To some there appears to be a lot in the proposal that has nothing to do with closures, including the control invocation syntax, null as a type, Unreachable, throws type parameters, function interface types, and "nonlocal" returns. In my Javapolis talk I tried to give an explanation for why these features are in the proposal from the practical point of view of what kinds of things would be possible that were not formerly possible. But that begs the question: why do we call it "Closures" for Java? In this blog post I'll try to show how the definition of closures relates to the features of the proposal, and identify which features of the proposal do (and which do not) result from the definition.

私たちの、Javaプログラミング言語にクロージャを追加するという提案に対して、いくらかの混乱がありました。結局のところ、Javaはすでに匿名クラスによってクロージャをサポートしているのでは?言語でサポートされている何かをさらに追加することの重要性は何なの?いくつかはクロージャとは無関係な提案も多くありました。control invocation syntax、型としてのNull、非到達性、型パラメータのthrow、関数インタフェースのタイプ、そして非局所的リターン。Javapolisのセッションでは、私はなぜこれらの機能が提案に含まれているかを、どんなことが以前は不可能で、そして可能になるのかという現実的な視点から説明しました。
けれど疑問は残ります。なぜこれを、Javaにとっての『クロージャ』と呼ぶのでしょうか?
この記事では、私は提案された機能がクロージャの定義とどのように関連しているかを紹介し、そして提案の中のどの機能がクロージャの定義に起因している(していない)かを明確にしようと思います。

Before discussing the definition of closures, it helps to understand the historical context in which the term was introduced.

さて、クロージャについて議論する前に、この用語が導入された歴史的な背景を説明しましょう。

Lisp was created in the late 1950's by John McCarthy and others at M.I.T. One feature of the language was function-valued expressions, signified by lambda. The name "lambda" was borrowed from a mathematical formalism known as the lambda calculus. Although Lisp was not based on an effort to model that formalism, lambda plays approximately the same role in Lisp as it does in the lambda calculus: lambda is the syntax for a function-valued expression. McCarthy's intent was that Lisp should be designed to be implemented very efficiently, ideally compiled. That desire for efficiency influenced the design of the language.

Lispは1950年代後半にM.I.TのJohn McCarthyらによって作られました。この言語の特徴の1つに関数を値とする式《function-valued expression》があり、lambdaで表現されています。「lambda」という名前はλ算法で知られる数学理論から借りたものです。形式主義をモデル化しようとする行いと同じ立場には立たなかったものの、Lispでもlambdaは「関数を値とする式のためのシンタックス」であるλ算法と同じ役割を果たしています。McCarthyは、Lispがとても効率良く実装できて、理想的な形でコンパイルできるようデザインされるべきだと考えていました。効率性への欲求はLispの言語設計にも影響しました。

Lisp used something called dynamic scoping. Logically, in a dynamically scoped language, when a variable reference is evaluated the runtime looks up the call stack until it finds a scope in which a variable of that name is defined. But as a practical matter variable references in a dynamically scoped language can be resolved in constant time simply by maintaining a value cell for each variable name; that value cell caches the variable's current definition. Dynamic scoping is easy to implement in an interpreter or compiler. Some very clever people had found ways to not only take advantage of dynamic scoping, but had developed what would now be thought of as programming patterns that depended deeply on it. But it was soon discovered that dynamic scoping suffered subtle problems, something the Lisp community called the FUNARG problem.

Lispではダイナミックスコープ《dynamic scope》と呼ばれるものを使っています。理屈の上では、動的スコープを用いる言語は変数の参照元が評価されるとき、ランタイムが変数名の定義されているスコープを見つけるまでコールスタックを探索します。しかし現実的な問題として、ダイナミックスコープを持つ言語ではシンプルに各変数名に対する「値のセル(value cell)」を管理することで、変数の参照先解決を一定時間で行っています。値のセルに変数の現在の定義をキャッシングしているのです。ダイナミックスコープはインタプリタやコンパイラにとって簡単な実装になります。何人かの聡明な方々は、ダイナミックスコープを活用する方法を見つけただけでなく、プログラミングパターンという、ダイナミックスコープに深く依存する思考方法を発展させました。しかしダイナミックスコープではFUNARG問題(訳注:日本語訳がここにあります)と呼ばれる繊細な問題を抱えていることもすぐに分かりました。


Now we fast-forward to the mid 1970's. On the radio you would hear*1 Elton John, Emerson Lake & Palmer, Joni Mitchell, The Captain and Tennille, John Denver, Paul Simon, Paul McCartney and Wings, ABBA, David Bowie, Janis Ian, Aerosmith, Fleetwood Mac, Heart, and Queen. A number of popular Lisp dialects were in use including InterLisp, MacLisp, UCI-Lisp, Stanford Lisp 1.6, and U. Utah's Standard Lisp. All of them were dynamically scoped. It was in this context that Guy Steele and Gerald Jay Sussman developed Scheme, a very simple Lisp dialect.

では、時代を1970年代中頃まで早送りしましょう。ラジオからはElton John, Emerson Lake & Palmer, Joni Mitchell, The Captain and Tennille, John Denver, Paul Simon, Paul McCartney and Wings, ABBA, David Bowie, Janis Ian, Aerosmith, Fleetwood Mac, Heart, そして Queenが聞こえてくることでしょう。(これは私ではなくGuy Steeleの、1970年後期の音楽に対する個人的インプレッションですからね)
当時の有名なLisp方言として、InterLisp, MacLisp, UCI-Lisp, Stanford Lisp 1.6, U. Utah's Standard Lispがありました。これらは全てダイナミックスコープを用いていました。SchemeというごくシンプルなLisp方言も、この時期にGuy SteeleとGerald Jay Sussmanによって作られました

One thing about Scheme was different.*2 Scheme was lexically scoped, like the lambda calculus and most mathematical notations, which means that a variable reference binds to the lexically enclosing definition for that name that was active at the time the enclosing lambda form was evaluated. To explain the semantics in terms of the implementation, evaluating a lambda expression was said to produce a "closure". This is a function value represented as an object that contains references to the current bindings for all the variables used inside the lambda expression but defined outside it. These are called the free variables. When this closure object, or function, is applied to arguments later, the variable bindings that had been captured in the closure are used to give meaning to the free variables appearing in the code. The term closure describes more than just the abstract language construct, it also describes its implementation.

Schemeは他と異なっていました(Schemeは最初のレキシカルスコープを持つLispでしたが、レキシカルスコープを用いた初めてのプログラミング言語ではありません。たとえばAlgol60などがそうでした。詳しくはLandinのThe Next 700 Programming Languagesを参照してください)。Schemeではレキシカルスコープを用いていて、λ算法や最も数学的な記述方法のようでした。内部で持つλ構文が評価されるときにアクティブになる名前の、構文的な包含定義を変数の参照は束縛していたのです。実装に関するこのセマンティクスを説明するために、「lambda式を評価すること」は「『クロージャ』を生成すること」と言われていました。これは関数の値であり、lambda式内で使われている(ただし式外で定義された)全変数の束縛への参照を含んだオブジェクトとして表現されます。この変数は自由変数と呼ばれています。このクロージャオブジェクト、または関数があとで引数に適用されるとき、クロージャ内に捕捉されている変数の束縛はコード内に現れる自由変数に意味を与えるために用いられます。クロージャという言葉には、単なる抽象化のための言語構造のみならず、実装の意味も含まれているのです。

To many in the Lisp community at the time, it didn't make sense to adopt a Lisp dialect with closures. Not only would it undermine common programming techniques but it would obviously be much less efficient. For a short time these issues were debated, and Guy Steele wrote a series of papers entitled Lambda the Ultimate _____ (where _____ is Imperative, Declarative, GOTO, or Opcode) to help explain the power of lexically scoped lambda (closures). Fast forward only a few years and the debate was largely settled: lexical scoping is Right and dynamic scoping is Wrong and we've all learned our lesson. Since that time the word closure is used to mean lexically scoped anonymous function, but the connotation is that it is possible to get the semantics wrong for any number of reasons, including bugs and concerns about implementation efficiency. It also hints that we should let the language design drive the implementation, not the other way around. Virtually every programming language, whether or not it has something like lambda and anonymous function values, uses lexical rather than dynamic scoping. The basic definition of a closure, however, shows its Lisp roots:

当時、多くのLispコミュニティにとって、Lisp方言にクロージャを採用することに意味はありませんでした。一般的なプログラミングテクニックを損なうだけでなく、明らかに非効率的だったのです。しばしこの問題について議論され、そしてGuy Steeleはレキシカルスコープなlambda(=クロージャ)が持つ力について説明した一連の論文:Lambda the Ultimate _____ (_____には「Imperative」/「Declarative」/「GOTO」/「Opcode」が入ります)を作成しました。数年後、議論はほぼ収束しました。レキシカルスコープは正しく、ダイナミックスコープは間違っていたのです。これはとても良い教訓になりました。そのときからクロージャは「レキシカルスコープである匿名関数」を意味する単語として使われるようになったのですが、この表現は幾つかの理由やバグ、実装効率によって解釈の違いが発生する可能性を常に持っていました。言語設計に実装を推進させるべきであり、それ以外の方法は採るべきではない、というヒントを与えてもいました。抽象的に見て、全プログラミング言語はlambdaや匿名関数などをサポートしている・していないに関わらず、ダイナミックスコープよりもむしろレキシカルスコープを採用しています。
Lispを起源とする、クロージャの基本的な定義は以下のとおりです。:

A closure is a function that captures the bindings of free variables in its lexical context.

クロージャとは、そのレキシカルコンテキストの中に自由変数の束縛を保持する関数である。

Around this time, Smalltalk was introduced. Smalltalk is the most pure and simple of the object-oriented languages: everything is an object. Object-oriented languages add a twist to lexical scoping. Rather than binding all names in the lexical scope, free variables appearing in methods are bound in the scope of the object that the method is a member of. In other words, names in a method are bound to members of the "current" object. The current object is accessible by the name "self". Another small but interesting detail is that you can return early from a method in Smalltalk using the syntax "^expression". We'll return (no pun intended) to the significance of this fact later.

さて、ここからはSmalltalkを紹介しましょう。Smalltalkは「すべてがオブジェクト」という、もっとも純粋・シンプルなオブジェクト指向言語です。オブジェクト指向言語はレキシカルスコープにひねり(twist)を加えました。レキシカルスコープ内の全ての名前をバインドするよりもむしろ、メソッド内の自由変数は、そのメソッドをメンバに持つオブジェクトのスコープに束縛されているのです。言い換えると、メソッド内の名前は「現在の」オブジェクトのメンバに対して束縛されています。現在のオブジェクトは"self"という名前によってアクセスできます。もう1つの小さな、けれど興味深いポイントは、"^expression"という文法を使うことで、メソッドから早々に返る(戻る)ことが出来ると言う点です。
後ほど、この事実の重要性に戻ってきますからね(いや、ジョークじゃないですよ)。

Methods aren't the only kind of code abstraction in Smalltalk. There is also an expression form for writing a block expression, which is essentially a lambda. Early dialects had limitations on them, but most modern Smalltalks do not. They are a true analog to Scheme's lambda. Free variables in a Smalltalk block are bound in the enclosing scope, which is typically the scope of some enclosing method. The result of evaluating a block expression is a closure, and like everything else it is an object. In this case the object has a method that you use to invoke the code of the block.

Smalltalkにおいて、メソッドとはコード抽象化程度のものではありません。まさしくlambdaのようにブロック構文を使った表現方法もあります。初期のSmalltallk方言には制限がありましたが、現在ほとんどのSmalltallkにおいてはそんなことはありません。
これらはSchemeでのlambdaと本当によく似ています。Smalltalkのブロック構文にある自由変数は(ブロックに)囲まれたスコープ──エンクロージャメソッドの典型的なスコープ──にバインドされていています。ブロック構文を評価した結果はクロージャであり、それ以外はオブジェクトのようでもあります。このケースでは、オブジェクトはブロック表記コードを実行するために使うメソッドを持っている、と言えます。

Anonymous functions (closures) were not blindly introduced into Smalltalk just because it seemed like a neat idea, or because they had worked out well in another language. Rather they were integrated fully and carefully into the language. Anonymous functions can properly be integrated into even an existing language, but there is an advantage when adding them early. As Guy Steele's papers demonstrated, they are so powerful that they subsume other language features. If you add them early, you might save yourself the trouble of adding language features that can instead be added as libraries. Smalltalk provides few control constructs directly in the language. Even the conditional "if" is provided as a library method and invoked using blocks.

匿名関数《Anonymous functions》(≒クロージャ)はSmalltalkに盲目的に取り入れられたわけではなく、上品なアイデアのようだったか、または開発者が他の言語に精通していたために取り入れられました。十分に注意深く、匿名関数は言語に組み入れられたのです。
匿名関数は既に存在している言語にでさえ正確に追加することができますが、ただし早期に導入するアドバンテージは存在します。Guy Steeleは論文で、匿名関数は取り入れる言語そのものを包含してしまうくらいパワフルなものだ、と記しています。つまり早期導入しておけば、ライブラリとして後から言語に導入することによるトラブルから身を護ることが出来るかもしれないのです。Smalltalkの言語仕様では制御構文をほとんど直接は提供していません。「if」条件文でさえライブラリのメソッドとして提供され、ブロック構文を用いて呼び出されるのです。

Two things distinguish blocks in Smalltalk from Scheme's lambda. First, the meaning of "self" within a block refers to whatever meaning it had in the enclosing context. Specifically, it doesn't refer to the closure object itself. Second, the syntax for returning from a method, "^expression", returns from the enclosing method; it doesn't return from the method representing the closure invocation. These two details are a natural consequence of the fact that, while Scheme has only one lexically scoped language construct (variable bindings), Smalltalk has three lexically scoped language constructs: name bindings (like Scheme), the referent of the return syntax, and the meaning of "self". The definition of closures above mentioned only "the bindings of free variables", but that is because the definition was written for the language Scheme, and name (variable) binding is the only lexically scoped construct in Scheme. Common Lisp also has "return" and "goto", and these too are captured lexically in a closure. In order to realize the full power of closures, described in Guy Steele's lambda papers, they must capture all lexically scoped language constructs. Generalizing the definition of closure to cover other languages would require using more language-neutral terminology: instead of "bindings of free variables" we would have something like "lexically scoped semantic language constructs." However, that obscures the origins of the term.

Smalltalkのブロック構文は、Schemeのラムダ構文と比べて2つの事柄により区別できます。1つ目は、ブロック内の「self」の意味が、包含するコンテキストが持つすべての意味も参照していることです。もっと正確に言えば、それ(self)がクロージャオブジェクト自身を指しているのではないことに注意が必要です。2つ目は、メソッドから返るための構文「^expression」が、包含しているメソッドから返ってくることです。クロージャの実行で表現されるメソッドから返っているのではありません。これら2つのポイントから、Schemeがレキシカルスコープ:変数束縛だけを持つ言語として構成されたこと、Smalltalkが3つのレキシカルスコープ:名前束縛(≒Scheme)、リターン時のシンタックスの参照、"self"の意味を持つ言語として構成されたことが自然に導き出されます。ここまでで述べたクロージャの定義は「自由変数の束縛」という意味でしたが、それはつまり、これがScheme言語のために定義された単語であるからです。Schemeでは、名前(変数)束縛が唯一の構成物ですから。Common Lispではさらに"return"や"goto"も持っていて、これらもまたクロージャ内でレキシカルに構成されています。Guy Steelのlambdaの論文をに書かれたクロージャの力をフルに引き出すためには、それらはすべてレキシカルスコープとして言語に組み込まれなければいけないのです。
他の言語をカバーすることを目的とした、クロージャの定義の一般化には、言語に沿った専門用語を用いることが必要です。「レキシカルスコープ化されたセマンティックな言語構成」のように用いる「自由変数の束縛」の代わりに、です。ところが、それが用語の元々(origin)を不明瞭にしてしまっているのです。

Fast forward more than 25 years, and we're once again listening to some of the same music we listened to in the late 1970's. We are now considering adding closures to Java, a significantly more complex language than either Scheme or Smalltalk. We're not considering them because they seem like a neat idea, or because they worked out well in other languages, or because we're bored. Rather we're considering them: because of the power and flexibility they will add to the programmer's arsenal; because of the improved readability we expect from programs that use closures instead of the existing alternatives; and because of a number of other recently proposed language extensions that will be unnecessary if closures are added. In order to get the full power of closures, they should capture all lexically scoped semantic language constructs. What are the lexically scoped language constructs in Java?

それから25年以上経った現在、私たちは1970年代のときと同じ音楽を聴いています。そして、私たちはJavaという、SchemeやSmalltalkとは比べ物にならない複雑な言語にクロージャを導入しようとしているのです。私たちがクロージャを検討している理由は、それが上品かつ巧妙なアイデアだからではなく、それらが多言語で枯れてきたからでもなく、退屈だからでもありません。そうではなくて、そのパワーとフレキシビリティがプログラマーにとっての引き出し《arsenal》を増やすこと、既存の他の方法の変わりにクロージャを使うことがプログラムの可読性を向上させること、そしてクロージャによって不要で大量な機能の追加が不要になるからです。
クロージャの本当の力を引き出すには、言語構造で必要なレキシカルスコープのすべての構文を捕捉するべきです。
では、Javaの言語構造のうち何がレキシカルスコープなのでしょうか?

  • The meaning of variable names.
  • The meaning of method names.
  • The meaning of type names.
  • The meaning of this.
  • The meaning of names defined as statement labels.
  • The referent of an unlabelled break statement.
  • The referent of an unlabelled continue statement.
  • The set of checked exceptions declared or caught.
  • The referent of a return statement.
  • The definite assignment state of variables.
  • The definite unassignment state of variables.
  • The reachability state of the code*3.

  • 変数名の意味
  • メソッド名の意味
  • 型名の意味
  • thisの意味
  • statementラベルとして定義された名前の意味
  • ラベルのないbreak文の指す先
  • ラベルのないcontinue文の指す先
  • The set of checked exceptions declared or caught.
  • return文の指す先
  • 変数の明確なアサイン文(? assignment state)
  • 変数の明確なアンアサイン文(? unassignment state)
  • コードの到達性を示す構文*4.


In addition, Java has one other significant difference from either Scheme or Smalltalk: Java is statically typed. That means that each expression has a type at compile-time. So if we add closures, we need to have some appropriate type for a closure. Since a closure is an anonymous function, it is natural to consider adding function types to the language. But this is not a mandate. As you can see by the two variations of our closures proposal (the nominal and the functional versions) we believe it is possible to add closures without adding function types with a limited loss of functionality (higher-order programming becomes impractical). Our proposal for closures addresses every item on this checklist. There are additional features of our proposal (the control invocation syntax and the closure conversion) that don't relate directly to the definition of closures, but which make them integrate very nicely with existing language features. And there are additional features not mentioned in the spec (such as proper tail recursion) that would be helpful to realize the full potential of closures.

それに加えて、JavaはSchemeやSmalltalkと大きく異なる特徴があります。:Javaは静的型チェックを行う言語です。つまり、コンパイル時点で式は型を持つのです。そのためクロージャを追加するならば、クロージャのために適した型を用意しなければなりません。クロージャは匿名関数であるため、言語に関数型を追加することを検討した方が自然です。しかしそれは絶対ではありません。私たちの2種類のクロージャへの提案(the nominal and the functional versions)から分かるように、私たちは、機能のロスをわずかながら伴う関数型の追加でなくても、クロージャを実装することが可能であると思っています(高階プログラミングは現実的ではありません)。クロージャへの提案はこのチェックリストにあるアイテムを指し示しています。クロージャの定義とは直接関係しない機能追加への提案(control invocation syntaxとクロージャのコンバージョン)もいくつかあります。しかし、すでにあるJava言語と、とてもうまく統一できています。


What about anonymous inner classes? It turns out that they don't pass muster on any item on this checklist. Let's set aside the fact that local variables from enclosing scopes must be final to be used inside an anonymous class. The problem is that variable names are simply not resolved in the correct scope. They are resolved in the scope of the anonymous class that you're creating, not the enclosing scope. If you're creating an instance of an interface then it's probably not too much of a problem because most interfaces don't have any (constant) variable definitions. But anonymous inner classes fail every other item on this checklist as well, most of them fatally. Most alternative proposals don't actually address any of the items on this list, and so fail to provide the power of closures any more than existing language constructs.

匿名インナークラス(anonymous inner classes)についてはどうでしょうか?このチェックリストには乗っていません。匿名クラスの中で用いられる、外側の変数はfinalでないといけないという事実は脇に置いておきましょう。問題は、変数名が正しいスコープの中では単純に解決できないことにあります。それら変数は作成した匿名関数のスコープ内で解決されます。外側のスコープではないのです。仮にinterfaceのインスタンスを作成したならば、interfaceは変数や定数の定義を持たないため、解決の困難さはそれ程問題にはならないでしょう。 しかし匿名インナークラスではチェックリスト内の他の致命的なアイテムと同様にうまくいかないのです。ほとんどの代替案はこのリストのアイテムのどれにも当てはまりません。それゆえ、既存の言語構造よりも強力なクロージャを提供することに失敗してしまうのです。

Setting aside all the programming language theory, don't anonymous inner classes provide, in practice, all of the advantages of closures? I believe I've already shown that the answer is no. It is certainly true that for any program you can write using closures, you can write a roughly equivalent program using anonymous inner classes. That's because the Java programming language is Turing-complete. But you will probably find yourself resorting to a significant and awkward refactoring of the code that has nothing to do with the purpose of the code. In fact, you can write a roughly equivalent program using assembly language if you have the stomach for such an effort. On the other hand, true closures increase the power of a language by adding to the kinds of abstractions you can express.

プログラミング言語のセオリーをすべて無視して、実際問題として匿名インナークラスはクロージャの利便性をすべて提供しているのでしょうか?
私は、その答はNoであるとすでに伝えています。クロージャを使って書ける幾多のプログラムにとっては真実であり、確かにほぼ同等のプログラムが匿名インナークラスによって書けてしまいます。これはJavaプログラミング言語がチューリング完全であるからです。けれどもあなたはしばしば、コードの目的とは関係ない大量で厄介な箇所のリファクタリングを行っていることに自分自身で気がつくでしょう。
実際のところ、その根性さえあればアセンブリ言語を使ってほぼ同等のプログラムを書けてしまいます。その一方で、真のクロージャは言語の持つ力を増大させるのです。表現可能な抽象化の一種を追加することによって。


-

  • lethevert氏のブログのコメント経由で拝見しました。訳に少し気になるところがあったのでコメントしておきます。 "function-valued expression" は「関数を値とする式」です。式を評価した値が関数になるものですね。 "higher-order programming" は「高階プログラミング」という用語です。関数を引数として別の関数に渡したり、関数から戻り値として関数を返したりすることを指します。 -- shiro(コメントいただいた内容をかときちが本欄に転載しました。ありがとうございました) (2008-07-01 22:10:18)
記事メニュー
目安箱バナー
注釈

*1 This is Guy Steele's impression of the late 1970's music era [personal communication].

*2 Scheme was the first lexically scoped Lisp, but certainly not the first lexically scoped programming language. Algol60, for example, was lexically scoped. See also Landin's The Next 700 Programming Languages.

*3 Arguably part of the lexical semantics or not, reachability state is valuable to capture in practice.

*4 レキシカルか非レキシカルか、セマンティクスに議論はあるが、到達性の構文は経験的に捕捉する価値はあります