讓我覺得愉快的是只有process算是 instantiatized 的東西,而不是任何各式各樣的資料
全都用物件類別包裹起來。
而thinking in function,我倒覺得不知道如何分別以函數方式思考或不以函數方式思考。
怎樣可稱為不以函數方式思考嗎?或許我可以說,在物件模型中,我無法以較漂亮的
函數方式思考。以前面所提的process來說,很明顯是物件導向,那麼如果以函數導向
思考process呢:例如,
例一:一個函數要接受二個參數可以變成normal form (可評估為一個結果值的情況),
而假如它只接受一個參數,還可以等待另一個參數而完成。後者這個樣式稱為
week head normal form。這是目前函數語言學術領域所知到的事實。
例二:一個process要接受二個訊息。當它接受了第一個訊息之後,變成一個本來該
接受二個訊息以完成工作,但目前只接受一個訊息並仍在等待第二個訊息的
process。做得到嗎?
像第二個套用到process情況的例子,概念上好像很正常,等實作起來就知道程式寫起來
有多麻煩了,一層又一層的receive-end和case-end。不過其實「等待一個訊息,然後
套用一個函數」這件事情顯然可以抽象為一個單元,像是:
-export([task/0]).
wait_for(Msg, Func, Args) ->
receive
{ Pid1, Msg } -> {data, apply(Func, Args)}
after
1000 -> {error, "Time Out")
end.
continuation([]) ->
{ data, [] };
continuation( [ { Stage1, Msg1, F, A } | R ] ) ->
{ Case, Data } = wait_for(Msg1, F, A)
, case Case of
data -> case continuation( R ) of
{data, Results} -> {data, [Data|Results]};
{error, Error} -> {error, Error}
end;
error -> { error , Data ++ " in " ++ Stage1 }
end.
task() ->
case continuation([ {"Stage1", 'hello', fun do_part_a/1, [a]}
, {"Stage2", 'world', fun do_part_b/2, [b1, b2]}
, ... ]) of
{ data, Results } -> consult(Results);
{ error, Error } -> io:format("~w.", [Error])
end.
這樣子就叫作 object-oriented process programming ,但其中我用continuation代替
普通的 function composition ( f(g(h())) ) 。對照為物件導向程式來看,上面task/1
程式有點像:
Task t1 = continuation.stage(1, 'hello', jobA, argsA)
.stage(2, 'world', jobB, argsB)
. ... ;
System.out.println(t1.result());