What have you found for these years?

2009-08-15

simple lambda calculus in scala

scala 的東西也算是翻過不少主題了,雖然沒有從頭仔細看過,
但總覺得應該沒有那麼難才對。可每次想到什麼,
好像也沒辦法直接寫成 scala 程式。因此我想稍微練習一下,
不然永遠只會流於嘴泡....(噴口水)

結果就是這個了。試著把之前 haskell 的程式翻譯成 scala.
雖然好幾次想去翻 haskell 的程式,不過最後還是沒翻,
成功用記憶寫出來了。

成果放在 gist 上 expr.scala

然後我有一個心得: "scala is scary"
他的語法多變性,比 ruby 還要誇張。
各式各樣類似但不太一樣的寫法,非常非常多。
而且各種怪怪的功能一堆,語法也用上不少符號,
我猜這大概是很難第一眼看過去,就記起來的主因吧?

相較於 haskell.... haskell 真是簡單簡潔又漂亮。
儘管如此,還是對 scala 很有興趣,
大概也是因為之前 c++ 寫慣了吧?
因此喜歡玩弄這些複雜性...
只是如果想寫出如 haskell 般漂亮的程式,大概就很勉強了。
混合性質的語言,大概就這麼回事。

*

稍微一點註解。第一行的:

implicit def envToTreeMap(x: Env) = x.map

這個其實沒用到。他的用處在於,讓你 env.get("x") 有效果。
一開始我是寫成 type Env = TreeMap[String, Val] with Eval
不過這樣會造成無法使用 new Env ...
可能是因為非 class 使用 with 會造成 type 變成 value, 而非 class.

後來試 class Env extends TreeMap[String, Val]
結果這問題很大,我不知道怎麼讓 insert 回傳 Env...
不知道這有沒有解?

最後就變成用 implicit 做。而且 implicit 有個規則,
一定要放在呼叫點的前面。其他的東西,測起來順序可以亂放,
也就是說像 haskell 那樣,哪個定義在前面都無所謂。

這樣很好,可以把實作細節丟到後面。而 implicit,
這種恐怖會亂跳的東西,強迫放在前面使得呼叫更清楚。
不然讀一個 class 進去,搞不好就會改變 runtime 行為。

scala 雖然是 static typing, 但很多地方卻異常動態 @@
這點也恐怕需要花點時間去適應,掌握何者動態,何者靜態。

呃總之這邊 implicit 就像是 ruby 的 method_missing,
他會在發現 method 不存在時,找一個存在的 conversion,
然後把 type convert 過去再呼叫 target type 存在的 method.

像是定義:

if @target.respond_to?(message) then @target.send(message)
else raise NoMethodError

這是我覺得 scala 最 scary 的功能。

*

聽說 scala 還能做某種程度的 duck typing...
def a (x : {def test : Int} ) = x.test + 1

我想 scala 確實可以說比 c++ 複雜了吧 @@
尤其是版本更新,好像還有一直在加東西...
歷史上,這種語言的下場通常都很慘。

不知道 scala 會如何?也不知道現在 d 發展得如何了...

2 retries:

Ben Wang said...

scala static type還是有缺點 當你定義了一個class 你就不能改他的定義
但ruby 是可以的
scala 會活的很久的 因為他是一種DSL (domain specific language) 不過 又可以當做general langauge

godfat 真常 said...

1. static typing 都是如此的,
定義修改了就不叫 static typing.
與其說這是缺點,不如說是定義。
但 scala 提供了 implicit,
這可以做某種程度的 dynamic typing.

2. 像是 SQL 這種才叫 DSL.
這跟活多久應該也沒什麼關係..
基本上 scala 理所當然是 general purpose 的。

Post a Comment

All texts are licensed under CC Attribution 3.0