[SML 7885] Re: 継続(continuation)というスタイル
AOKI Atsushi
atsushi @ cc.kyoto-su.ac.jp
2010年 12月 19日 (日) 17:16:28 JST
青木@京都宇治です。
先のメールにて、継続(コンティニュエーション・パッシング・ス
タイル)を用いて階乗計算を行うプログラムを紹介しましたが、
| factorial |
factorial :=
[:n :continuation |
(n isInteger not or: [n negative]) ifTrue: [^self error: 'boo!'].
n = 0
ifTrue: [continuation value: 1]
ifFalse: [factorial value: n - 1 value: [:a | continuation value: a * n]].
n halt].
factorial value: 10 value: [:a | ^a]
その実行過程をプログラム(ソースコード)として生成し、整形し、
実行し、その結果を獲得するプログラムを書き下ろしてみました。
| anInteger anInterval aStream aCode aTree aResult |
anInteger := 10.
anInterval := 0 to: anInteger.
aStream := String new writeStream.
aCode :=
[anInterval do:
[:n |
| s |
s := n printString.
aStream nextPutAll: '| con' , s , ' | con' , s , ' := '.
n < anInterval last
ifTrue: [aStream nextPutAll: '[:a' , s , ' | ']
ifFalse: [aStream nextPutAll: '[:a | ^a]. ']].
anInterval reverse do:
[:n |
| s |
s := n printString.
aStream nextPutAll: 'con' , s , ' value: '.
n > anInterval first
ifTrue:
[| r |
r := (n - 1) printString.
aStream nextPutAll: 'a' , r , ' * ' , s , ']. ']
ifFalse: [aStream nextPutAll: '1']].
aStream contents]
ensure: [aStream close].
aTree := Refactory.Browser.RBParser parseExpression: aCode.
aCode := aTree formattedCode.
aResult := Compiler evaluate: aCode.
Transcript
clear;
nextPutAll: aCode;
cr;
nextPutAll: '==> ';
nextPutAll: aResult printString.
^aResult
トランスクリプトには次のように出力されます。conNがfactorialN
のコンティニュエーションを意味しています。
| con0 |
con0 :=
[:a0 |
| con1 |
con1 :=
[:a1 |
| con2 |
con2 :=
[:a2 |
| con3 |
con3 :=
[:a3 |
| con4 |
con4 :=
[:a4 |
| con5 |
con5 :=
[:a5 |
| con6 |
con6 :=
[:a6 |
| con7 |
con7 :=
[:a7 |
| con8 |
con8 :=
[:a8 |
| con9 |
con9 :=
[:a9 |
| con10 |
con10 := [:a | ^a].
con10 value: a9 * 10].
con9 value: a8 * 9].
con8 value: a7 * 8].
con7 value: a6 * 7].
con6 value: a5 * 6].
con5 value: a4 * 5].
con4 value: a3 * 4].
con3 value: a2 * 3].
con2 value: a1 * 2].
con1 value: a0 * 1].
con0 value: 1
==> 3628800
------------------------------------------------------------
AOKI Atsushi http://www.cc.kyoto-su.ac.jp/~atsushi/
SML メーリングリストの案内