Concurrent Clean : Threading
スレッドの話ではない。関数プログラミングなどで、状態を次々と受け渡して行くような書き方を指していう言葉だ。
Haskellがモナドを使ってThreadingを隠蔽してしまったのに対して、Cleanでは一意性型属性を使ってThreadingを陽に表現する。
ところで、Cleanでプログラミングをしていると、状態変数がわいわいと数が増えてしまって、それらの管理に困ってしまうことが起こりえる。たとえば・・・
f w # (_,f0,w) = fopen "file01.txt" FReadText w (_,f1,w) = fopen "file02.txt" FReadText w (_,f2,w) = fopen "file03.txt" FReadText w (_,f3,w) = fopen "file04.txt" FReadText w (_,f4,w) = fopen "file05.txt" FReadText w (_,f5,w) = fopen "file06.txt" FReadText w (a,f0,f1,f2,f3,f4,f5) = app f0 f1 f2 f3 f4 f5 (_,w) = fclose f0 w (_,w) = fclose f1 w (_,w) = fclose f2 w (_,w) = fclose f3 w (_,w) = fclose f4 w (_,w) = fclose f5 w = (a,w)
こういうときに、状態変数を別の上位の状態変数に置き換えてやるようなことができたら便利だなぁとか思いました。つまり・・・
appWorld :: *a (*a -> (b,*a)) *World -> (b, *World) readFile0 = appWorld f0 freadc readFile1 = appWorld f1 freadc readFile2 = appWorld f2 freadc readFile3 = appWorld f3 freadc readFile4 = appWorld f4 freadc readFile5 = appWorld f5 freadc
みたいにグローバルに定義しておけば、
# (c,w) = readFile0 w
のように、*Fileの代わりに*Worldを渡して関数を呼び出せるようになれば、トップレベルからは個々の状態変数だけでなく*Worldだけを渡せばよいようになる。
問題は、ぱっと思いつくところで、代入がないのでグローバルな定義を初期化できないことと、状態変数の破棄後にこれらの関数をどのように安全に取り扱うかということ。
まだ、かなり推敲の足りないアイデアなので、もうしばらく考えます。