2008-01-08

Call-by-Need, 関数ポインタについて

発展問題のCall-by-Needが完成!

しかし、今日はフーリエ懐石のマスマティカまで手が回らなかった。
やっぱ学校始まると、授業の文だけ課題をこなす時間が少なくなるからか。
それに授業に集中する分の体力も減ってしまうし。。。

残り一ヶ月の追い込みスケジュールに支障が無いように、そこらへんは要チェックしないとな。



[Call-by-Need]
Call-by-Nameを改良(?)してできた引数受渡機構。
Call-by-Nameが毎回借り引数が来るたびに式を評価するのと違い、
一度仮引数を評価したら、その評価値をその後の式に適応させていく。

>>外側の関数適用を先に評価
>>同じ式は1回だけ評価、結果を使い回す
>> let f x = x * x in f (5 + 3)
>>→ f (5 + 3)
>>→ (5 + 3) * (5 + 3) # 2つの (5+3) は同一
>>→ 8 * 8
>>→ 64
>> cf. “Haskell” (Call by need な関数型言語)

„ 利点
„ 計算能力が高い (call by name と同じ)
„ 1つの式の評価は1回で済む
„ 欠点
„ 実装が遅くなる
„ 式の評価タイミングは依然制御困難
„ Sharing があるのでさらに複雑に

(refer to the lectue "ML" Univ of Tokyo)

よって、例えば
int x=3, y=5, i;
for(i=0; i<100 ; i++) numlist[index] = index;
func(x, numlist[x*y]);
echo 「"numlist[X] != X"となっている部分を出力する」;

func(int a, int b){
a += b;
i++;
j++;
b += 30;
}

※処理系は脳内コンパイラ。

とすると、出力結果は
numlist[15] = 45
となる。



[関数ポインタについて]
関数も変数と同様に名前を持ち、その実体(命令列/データ)は
メモリ上に格納され、その格納領域を指し示すための参照が、
関数名/変数名に割り当てられる
「フォン・ノイマン・アーキテクチャ」において、
データと命令はどちらもメモリ上に格納されるバイト列になる。

したがって、関数/変数の実体の格納位置をポインタで
表現するCでは、関数のポインタを扱うことができる。
つまり、関数ポインタ値を代入できる変数が宣言できる

int型の変数mと、int型のデータへのポインタ変数
nの宣言
intを返す関数fと、intへのポインタを返す関数gと
intを返す関数へのポインタ変数hの宣言
int m;
int *n;
int f();
int *g();
int (*h)();

[reference: the Lecture of "PLT", Waseda University]

0 件のコメント: