私は Objective-C でプログラミングしており、Scala、Python、Javascript について少し知っています。
私は Obj-C のブロックに慣れていますが、以前のバージョンの言語では解決できなかった具体的な問題を知りたいです。また、ブロック、クロージャー、関数リテラル、名前付き関数、匿名関数は同じものですか?
いくつかのコード例で答えることができれば、それは素晴らしいことです。
私は Objective-C でプログラミングしており、Scala、Python、Javascript について少し知っています。
私は Obj-C のブロックに慣れていますが、以前のバージョンの言語では解決できなかった具体的な問題を知りたいです。また、ブロック、クロージャー、関数リテラル、名前付き関数、匿名関数は同じものですか?
いくつかのコード例で答えることができれば、それは素晴らしいことです。
まず、タイトルの質問に答えるために:
プログラミング言語でブロック、関数リテラル、クロージャーが必要なのはなぜですか?
回答 #1: ありません。Brainfuckはそれらがなくてもチューリング完全です。
答え #2: 私たちは怠け者で、クロージャーは便利で使いやすいからです。
彼らはどのような特定の問題を解決しますか?
それらは特定の問題を解決しません。Objective-C に慣れている場合は、関数ポインターについて聞いたことがあるはずですよね? ブロックがどこかで使用されるたびに、関数ポインターを使用して、そのコード片を同等のスニペットに変換できます。クロージャーがプログラマーにもたらす大きな成果は、読みやすさです。クロージャー (ブロック、ラムダ関数など) は、 「通常の」グローバル関数とは異なり、作成された場所で使用できます (そして使用されます)。次の 2 つのコードを考えてみましょう (2 つの架空のメソッドは、Cocoa ネットワーク API に関して発明されました)。
void url_callback(void *data, size_t length)
{
NSLog(@"Received data %p of size %zu", data, length);
}
[connection sendAsyncRequestWithHandlerFPtr:&url_callback];
対
[connection sendAsyncRequestWithHandlerLambda:^(void *data, size_t length) {
NSLog(@"Received data %p of size %zu", data, length);
}];
もちろん、2 番目のものでは、コードを読んだ人には、それが何をするかは明らかです。最初の例では、データを受信したときに何が起こるかを理解できるように、関数の実装 (存在する場合) に到達するために上下にスクロールする必要があります。
ブロック、クロージャー、関数リテラル、名前付き関数、無名関数は同じものですか?
いいえ、そうではありません。(とても。)
クロージャーと無名関数は、数学および/または CS 理論の概念です。それらは、第一級の値であるサブルーチンを記述します。
ブロックはクロージャの特定の実装であり、Apple が C (および結果として Objective-C) プログラミング言語の拡張として実現したものです。
名前付き関数式は、クロージャーとグローバル関数の利点を組み合わせた JavaScript 機能です。