Personal tools
You are here: Home ブログ uchida 関数内関数欲しいな
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Categories
JavaScript
Go
Ada
Delphi
junk
 
Document Actions

関数内関数欲しいな

(Goを)さわってみた感想は次回書きます。
唐突ですが私の得意言語はDelphi(Object Pascal)です。
Pascalが好きではない人に何か言ってやろうと思ってたんですが、勝てそうにないんで代わりに以前書いたDelphiのプログラムを貼ってお茶を濁すことにしました。

Goで好きになれそうにないところは関数内関数がないあたりです。
とりあえずコード書いて、似たようなコードやレイヤーが違うコードを関数内関数で括り出しといて、汎用的に使えそうならグローバルやprivateな関数にする、というプロセスは慣れるとなかなかいいものです。
Lispもlabelsを使うCommon Lispより普通に関数が書けるSchemeの方が好きです。
ちなみにGoの

var f := func() {
fmt.Printf("closure %c", a[0]);
};

を関数内関数と呼ぶには抵抗があります。最適化と慣れの問題かもしれませんが。

関数内関数を作れるとその関数ポインタをどうするのか、という問題が発生します。
Delphiでは関数内関数のポインタをとれないことにして問題を解決しています。
正確に言うとこんな感じだったはず(未テスト)。

// 普通の関数を変数に入れるのはOK
procedure Hoge;
begin
Writeln('hello');
end;

type
TProc = procedure;
var
hoge: TProc;
begin
hoge := Hoge;
end.
// 関数内関数を変数に入れるのはコンパイルエラー
procedure Test;
procedure Hoge;
begin
Writeln('hello');
end;
var
hoge: TProc;
begin
hoge := Hoge; // コンパイルエラー
end;
// これはOK、ただしHoge内でTestのローカル変数を触ると実行時エラー
procedure Test;
procedure Hoge;
begin
Writeln('hello');
end;
var
hoge: TProc;
begin
hoge := @Hoge;
end;

しかしytqwerty氏の発明した関数内関数渡しの方法を使うと親関数のローカル変数を触れるようになります。
正確に理解できてはいないのですが、関数内関数を呼ぶ時のスタックのポインタを連れ回してCallする前に書き換えてしまう技のようです。

これをつかってprototype.jsのEnumerable的なものをDelphiで作成してみたのがこれです。
enumerable.zip
IEnumerableを実装するとEnumerableをmixinしたのと似たようなことになります。
Javaな人は「interfaceを実装することがなんでmixinなんだ?」と思われるかもしれませんが、Delphiには「委任」という便利な機能があるのです。
(この辺の「Delphiのinterfaceは使えない」という世間の認識に対してもそのうち何か言いたい)

まあ作ってみたはいいものの実用には使わないと思います。
ちなみに最近のDelphiだと無名関数が使えるらしいです。

やっぱり単なる慣れの問題なのかなあ?

Category(s)
junk
Delphi
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/95a26570518595a265706b3230573044306a/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.