PureScript 是什麼?有什麼特性


這周末在看 PureScript。之所以要看是因為之前寫了一陣子的 TypeScript,感覺工具方面確實優秀,可惜沒有 higher-kinded types 和 algebraic datatypes,這就使得某些 library (比如 React Native Experimental Navigator API,GitHub - ericvicenti/navigation-rfc: Better Navigation in React Native)沒法很準確的定義出來。有沒有別的選擇呢?從 Github 上的星星數來看,ClojureScript 有 5000+,可惜是 untyped 的;bucklescript 有 500+,但是我基本沒寫過 OCaml... Elm 有 2000+,不過整個語言看起來挺受限的,必須得用其提供的唯一的方法寫 FRP。Scala.js 和 PureScript 都有 2000+,只是 Scala 我估計連五千行都沒寫過,還是先看後者吧。

PureScript 跟 Haskell 巨像,除了一部分功能(如 -XTypeFamilies 等)沒有之外。好處不用多說了。跟 GHCJS 相比,PureScript 編譯出來的 JavaScript 輕便得多——PureScript 是 strict 的,幾乎沒有 runtime(大概只有 typeclass 的 dict-passing?),JS FFI 極為方便。編譯出來的 JS 基於 CommonJS module,這也大大方便了跟 JS 之間的交互。事實上我認為一個編譯到 JS 的語言確實是得要跟 JS 在語義和運行時上不能差的太遠。GHCJS 是 lazy 的,其 rts 還自帶 green thread / scheduler / GC 等等等等,聽起來很吊,實際用起來發現跟 JS 交互特別麻煩,還是容易讓人懵逼的。我認為這些語言(指編譯到 JS 的語言)更多的心思應該放在 compile-time 的功能上,像 generics-syb(PureScript 也支持!)和 template haskell(這個就沒有了)就很好。

PureScript 用的不是 IO monad 而是 Eff monad,後者看起來分的更為細。跟 monad transformers 相比,extensible effects 在理論上的好處都有啥?這我還不太了解,希望樓下補充。直覺上來看,extensible effects 不像 transformers 那樣需要手動 lift,也不像 mtl 那樣需要 define 一百種不同的 typeclass 和一萬種他們之間的關係。但是 Eff 也有壞處:分的太細的話,類型會特別長,而且 type inference 上好像有時候不行,相比之下 IO / StateT 這種具體的類型就不會有 infer 不出來的情況。

說到 extensible effects,不像 Haskell 還得去費勁模擬,PureScript 本身就支持 row polymorphism,Eff 也是用它實現的。row polymorphism 是什麼呢?直覺上來看它跟 subtyping 很像,據說它比 subtyping 更方便做 type inference。具體理論我還不太懂,得多讀讀書.. 目前(PureScript 0.8)還不支持 row constraints 和 type equality,呃,功能上還是弱了一些。

同樣,PureScript 里的 record 也比 Haskell 的簡潔——你可以直接用 a.b 來訪問 a 的 b field,不會有撞名的情況。當然了,對於更加複雜的需求,Lens 依然是支持的。

工具方面還不錯,pulp 編譯打包一條龍,還自帶 tree shaking;psc-ide 提供一大坨跟 ghc-mod 類似的功能(補全,自動 import,case split);Atom 和 Emacs 都有現成的跟這些工具集成的插件,可以拿來直接用。編譯速度聽說是一個問題,我感覺肯定是比 TypeScript 慢的,不過暫時還可以接受。

——————

只是,回頭來看,這麼多編譯成 JS 的語言里,雖然一山更有一山高,但是從大公司背書的角度上來看,還是 TypeScript 穩呀.. 偷克穩,穩克莽,但是過於求穩有什麼意思呢 :P


……誰邀請的

purescript 我印象就是我配了兩次環境,每次半小時,最後還是沒法編譯一個文件

對比隔壁 idris,下完就能用,這是何等卧槽的差距……


推薦閱讀:

精通 Haskell 是一種怎樣的體驗?
Haskell等語言中的模式匹配在C++中如何實現?
編程語言中的「組合性」是什麼意思?
柯里化對函數式編程有何意義?
C++、Haskell、Scala 和 Rust 究竟哪個最複雜?

TAG:JavaScript | 編程語言 | Haskell |