TypeScript Nim交替使用細(xì)節(jié)分析
交替使用 TypeScript 和 Nim 的一些感想
我之前的背景主要是 js 和 ClojureScript, 對類型了解很有限,到 Nim 算是才開始長時(shí)間使用靜態(tài)類型語言吧. TypeScript 那只當(dāng) type checker.
Nim 的明顯問題
JavaScript 到底是 Google 砸錢了的, 調(diào)試的體驗(yàn)真的是好.
至于 Nim, 大部分的報(bào)錯靠著類型信息倒是也能定位出來,不過沒有趁手的斷點(diǎn)調(diào)試工具, 經(jīng)常要靠大量的 log, 我也挖得不夠深.
Profiler 我也用過, 導(dǎo)出的是文本的調(diào)用棧和開銷占比, 當(dāng)然沒 Chrome DevTools 清晰.
VS Code 使用體驗(yàn)自然也遠(yuǎn)遠(yuǎn)不能跟 TypeScript 比, 我直接 Sublime 了.
Nim 的 echo 首先就很讓我頭疼, 沒有自動加空格, 挺煩的.
Nim 沒有內(nèi)置的 string interpolation, fmt 不確定是函數(shù)還是 macro.
通常 fmt"balbla "
這樣的語法可以插值, 但是效果完全不如語言級別的插值方便,這個寫法中如果有 {
或者 }
還需要手動處理, 我在使用的時(shí)候就感覺比較糟心.
要在語言里邊實(shí)現(xiàn) interpolation, JavaScript 或者 CoffeeScript 都不會這么麻煩.
Nim 類型和運(yùn)行時(shí)的一致性
TypeScript 雖然有很風(fēng)騷的類型系統(tǒng), 但我也沒用著 strict, 也不是所有依賴都 ts.
然后偶爾會遇到寫了類型但是底下完全不是那么回事, 就很莫名.
Nim 的類型跟數(shù)據(jù)是直接對應(yīng)的, 使用當(dāng)中除了一些 edge case, 都能對應(yīng)上,意味著類型檢查報(bào)錯的地方修復(fù), 代碼對應(yīng)的報(bào)錯也就解決了,這讓我感覺到類型才是可靠的. 當(dāng)然, 很多靜態(tài)語言應(yīng)該就是這樣子.
Method call syntax
Nim 不是面向?qū)ο笳Z言, 里邊的 object 大致對應(yīng) C 的 struct, 而不是對象.
object 里邊就是數(shù)據(jù), 這個還是比較習(xí)慣的.
不過代碼觀感上, Nim 還是有點(diǎn)貼近 js 這樣支持 OOP 的寫法的,我是說大量的 a.b(c)
這樣方法調(diào)用的語法, Nim 里邊叫做 Method call syntax.
也剛知道這在 D 里邊已經(jīng)有了, Wiki 上都明確說了:
https://en.wikipedia.org/wiki...
這個特性對應(yīng)的 Nim 代碼是這樣子的:
type Vector = tuple[x, y: int] proc add(a, b: Vector): Vector = (a.x + b.x, a.y + b.y) let v1 = (x: -1, y: 4) v2 = (x: 5, y: -2) v3 = add(v1, v2) v4 = v1.add(v2) v5 = v1.add(v2).add(v1)
最初我使用的時(shí)候沒有在意, 但是隨著遷移一些代碼到 ts, 才感受到靈活.
在 JavaScript 當(dāng)中, 繼承, 多態(tài), 依賴 class 結(jié)構(gòu)才能實(shí)現(xiàn),這也意味著我要定義 class, 然后 new instance, 然后才能用上.
但定義了 class 也就意味著這份數(shù)據(jù)不是 JSON 那樣直白的數(shù)據(jù)了.
我對 OOP 使用不多, 但是思來想去大致也理解, 動態(tài)類型能做到 JavaScript 這樣已經(jīng)很強(qiáng)了.
Nim 的多態(tài)是通過編譯器判斷類型來實(shí)現(xiàn)的, 比如前面的 add
可以有很多個 add
,
proc add(x: Y, y: Y): Z = discard proc add(x: P, y: R): Q = discard
后邊遇到 o.add(j, k)
根據(jù)類型在編譯時(shí)候就能實(shí)現(xiàn)多態(tài)了.
當(dāng)然這在 JavaScript 靠 class 是能夠?qū)崿F(xiàn)的, 但那就一定要把數(shù)據(jù)操作綁在一起了.
長期使用受 Scheme 影響的語言, 對 class 這個臃腫的做法就很難適應(yīng).
有類型的情況下, 在這套方案當(dāng)中 overloading 很自然的,比如 Nim 當(dāng)中對類型 A
定義 equality 判斷的寫法這這樣的,
type A = object x: number proc `==`(x, y: A): bool = discard
沒有耦合在一起, 意味著我引用 A
類型在另一個項(xiàng)目也能自行擴(kuò)展,而且這基于類型的, 不會修改到原始的模塊當(dāng)中, 不影響到其他引用 A 的代碼.
這一點(diǎn), 我的代碼從 Nim 轉(zhuǎn)譯到 TypeScript 就比較頭疼,因?yàn)槲叶x數(shù)據(jù)結(jié)構(gòu)的訪問和判斷需要 overload 這些個 array accessing 和 equality,我一時(shí)半會也想不出來 TypeScript 當(dāng)中能怎么做, 只能用 mutable data 在運(yùn)行時(shí)強(qiáng)行模擬.
Nim 里邊就很簡單, 我對 []
進(jìn)行重載, 后邊就能 ys[index]
直接用了:
proc `[]`[T](xs: MyList[T], idx: number): T = discard
這個對于 iterator 的場景也是類似, 定義了 iterator 就能直接寫 for..in 了.
iterator 這在 JavaScript 當(dāng)中也行, 只是說 Nim 當(dāng)中很多運(yùn)算符都能自己重載.
然后好處也是比較明顯的, 比如我重構(gòu)了操作內(nèi)部實(shí)現(xiàn), 但使用的地方基本不需要調(diào)整.
而在 JavaScript 里邊, 長久我就習(xí)慣性直接面對 Array 跟 Object 了.
沒有碰過 Java 跟 C#, 碰過語言當(dāng)中這套玩法跟 Haskell 倒是挺像的,Haskell 從 class 產(chǎn)生 instance 的時(shí)候可以定義一些函數(shù), 就很靈活.
(具體 Haskell type class 高階玩法真是還玩不起來.)
不過 Nim 相比來說, 簡化是簡化了, 但這個語法糖在編碼當(dāng)中就是很方便.
也因?yàn)槿笔н@個功能, 導(dǎo)致我對 Clojure 跟 TypeScript 這都有點(diǎn)不適應(yīng)了.
動態(tài)數(shù)據(jù)的類型
轉(zhuǎn)譯代碼還發(fā)現(xiàn)的問題是由于 JSON 跟 EDN 極為便利,引起我在大量代碼當(dāng)中直接使用 Array 和 Map 直接表示數(shù)據(jù),這個不能算錯, 但數(shù)據(jù)在 Nim 當(dāng)中這些都是明確用類型表示的,也意味著在 Nim 當(dāng)中有明確的結(jié)構(gòu)進(jìn)行判斷, explicitly...
反觀我的 TypeScript 代碼, 大量的 Array.isArray
,然后還有那個不知道怎么說的 typeof x === 'object'
的尷尬,在類型系統(tǒng)當(dāng)中使用習(xí)慣之后, 回過頭感覺特別不踏實(shí),然后我自動跑去折騰 instanceof
的玩法來做對應(yīng)功能了.
當(dāng)然, JSON 或者 EDN 通用地表示各種數(shù)據(jù), 確實(shí)在通用型來說非常好,我跨項(xiàng)目調(diào)用數(shù)據(jù), 這些動態(tài)類型就是直接通用的結(jié)構(gòu),在 Nim 當(dāng)中, 一般傳遞數(shù)據(jù)是會涉及到一些類型轉(zhuǎn)換, 寫寫是有點(diǎn)麻煩的.
我不是很能衡量那種方案是更好, 但是對于底層類庫, 我是希望有明確類型的.
內(nèi)存相關(guān)問題
因?yàn)橐幾g到 C 運(yùn)行, Nim 當(dāng)中的數(shù)據(jù)結(jié)構(gòu)多少還是要涉及到一點(diǎn)內(nèi)存的部分.
不過好在 Nim 當(dāng)中指針絕大部分已經(jīng)封裝成 ref 了, 也很少要去操心.
主要是感覺就是不同數(shù)據(jù)結(jié)構(gòu)之間性能的區(qū)別比較容易體現(xiàn)出來了.
這個在 JavaScript 這邊, JIT 老是偷偷幫忙優(yōu)化, 自己寫出問題沒那么容易察覺.
我感覺到如果我早使用 Nim 的話, 對算法和性能的朦朧感就會輕很多.
而能觸碰到內(nèi)存, 也就意味著內(nèi)存管理會遇到一些問題,我之前遇到, 似乎是用 macro 的時(shí)候, 遇到語言內(nèi)部的代碼出錯了,然后 illegal memory access, 這就變得很無助了,論壇上給我的幫助讓我編譯 Nim 編譯器本身然后打 log 來獲取細(xì)節(jié),這個體驗(yàn)還是蠻新奇的, 反正 V8 我是沒有自己帶參數(shù)編譯過...
至少我目前用到的還不需要很清晰了解內(nèi)存布局細(xì)節(jié), 以后再看吧...
一些語法細(xì)節(jié)
Nim 當(dāng)中的語法糖還是挺多的, 有很多使用 CoffeeScript 時(shí)候那種輕快的感覺,比如說 JavaScript 現(xiàn)在不好加語言級別的 range,這在 Nim 當(dāng)中直接用 ..
或者 ..<
就能生成 range 了:
for i in 0...<n: echo i
然后 if 在 Nim 當(dāng)中雖然比起 CoffeeScript 有那么點(diǎn)不順手, 但也還是表達(dá)式:
let a = if b: c elif d: e
這樣的代碼轉(zhuǎn)到 TypeScript 馬上就變得挺長了, 我更不能用三元表達(dá)式去犧牲可讀性.
當(dāng)然還是跟 CoffeeScript 去比的話, Nim 畢竟還要考慮類型, 沒的那么靈活.
對于代碼格式化, Nim 有個內(nèi)置的 nimpretty 命令.
我沒怎么用, 只是試了一下, 快當(dāng)然是很快的.
不過我用縮進(jìn)寫代碼本來就已經(jīng)精確管理空格了, 再弄一個好像沒必要, 也沒手寫靈活.
其他
TypeScript 的強(qiáng)大是我不得你承認(rèn)的. 為此我對 AssemblyScript 還挺期待的.
但是隨著 Nim 帶來的這些感受, 我也起了一些疑惑.
比如說基于 WebAssembly 我們將來有個更好的瀏覽器語言了, 怎樣才更好?
一方面要兼顧 Web 應(yīng)用大量的界面處理的場景, 一方面高性能和靈活,單純 AssemblyScript 這樣, 總感覺還是不夠的吧
以上就是TypeScript Nim交替使用細(xì)節(jié)分析的詳細(xì)內(nèi)容,更多關(guān)于TypeScript Nim使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
TypeScript使用noImplicitAny實(shí)戰(zhàn)解析
這篇文章主要為大家介紹了TypeScript使用noImplicitAny實(shí)戰(zhàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08TypeScript手寫一個簡單的eslint插件實(shí)例
這篇文章主要為大家介紹了TypeScript手寫一個簡單的eslint插件實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02高級前端面試手寫扁平數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)Tree
這篇文章主要為大家介紹了高級前端面試手寫扁平數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)Tree示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06TS報(bào)錯Cannot?find?module?'xxx'?or?its?correspo
這篇文章主要為大家介紹了TS報(bào)錯Cannot?find?module?'xxx'?or?its?corresponding?type?declarations解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08jsf實(shí)現(xiàn)微信小程序簡潔登錄頁面(附源碼)
這篇文章主要介紹了實(shí)現(xiàn)微信小程序簡潔登錄頁面?,對于正在學(xué)習(xí)的小伙伴都有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-01-01TypeScript實(shí)現(xiàn)十大排序算法之歸并排序示例詳解
這篇文章主要為大家介紹了TypeScript實(shí)現(xiàn)十大排序算法之歸并排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02ThreeJS使用紋理貼圖創(chuàng)建一個我的世界草地方塊
這篇文章主要為大家介紹了ThreeJS使用紋理貼圖創(chuàng)建一個我的世界草地方塊的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06