我以前的背景主要是 js 和 ClojureScript, 对类型了解颇有限,
到 Nim 算是才开始长时间使用静态类型语言吧. TypeScript 那只当 type checker.数据结构
JavaScript 究竟是 Google 砸钱了的, 调试的体验真的是好.
至于 Nim, 大部分的报错靠着类型信息却是也能定位出来,
不过没有趁手的断点调试工具, 常常要靠大量的 log, 我也挖得不够深.函数
VS Code 使用体验天然也远远不能跟 TypeScript 比, 我直接 Sublime 了.工具
Nim 的 echo 首先就很让我头疼, 没有自动加空格, 挺烦的.编码
TypeScript 虽然有很风骚的类型系统, 但我也没用着 strict, 也不是全部依赖都 ts.
而后偶尔会遇到写了类型可是底下彻底不是那么回事, 就很莫名.调试
Nim 的类型跟数据是直接对应的, 使用当中除了一些 edge case, 都能对应上,
意味着类型检查报错的地方修复, 代码对应的报错也就解决了,
这让我感受到类型才是可靠的. 固然, 不少静态语言应该就是这样子.code
Nim 不是面向对象语言, 里边的 object 大体对应 C 的 struct, 而不是对象.
object 里边就是数据, 这个仍是比较习惯的.
不过代码观感上, Nim 仍是有点贴近 js 这样支持 OOP 的写法的,
我是说大量的 a.b(c)
这样方法调用的语法, Nim 里边叫作 Method call syntax.
也刚知道这在 D 里边已经有了, Wiki 上都明确说了:
https://en.wikipedia.org/wiki...orm
这个特性对应的 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)
最初我使用的时候没有在乎, 可是随着迁移一些代码到 ts, 才感觉到灵活.继承
在 JavaScript 当中, 继承, 多态, 依赖 class 结构才能实现,
这也意味着我要定义 class, 而后 new instance, 而后才能用上.
但定义了 class 也就意味着这份数据不是 JSON 那样直白的数据了.ip
我对 OOP 使用很少, 可是思来想去大体也理解, 动态类型能作到 JavaScript 这样已经很强了.
Nim 的多态是经过编译器判断类型来实现的, 好比前面的 add
能够有不少个 add
,
proc add(x: Y, y: Y): Z = discard proc add(x: P, y: R): Q = discard
后边遇到 o.add(j, k)
根据类型在编译时候就能实现多态了.
固然这在 JavaScript 靠 class 是可以实现的, 但那就必定要把数据操做绑在一块儿了.
长期使用受 Scheme 影响的语言, 对 class 这个臃肿的作法就很难适应.
有类型的状况下, 在这套方案当中 overloading 很天然的,
好比 Nim 当中对类型 A
定义 equality 判断的写法这这样的,
type A = object x: number proc `==`(x, y: A): bool = discard
没有耦合在一块儿, 意味着我引用 A
类型在另外一个项目也能自行扩展,
并且这基于类型的, 不会修改到原始的模块当中, 不影响到其余引用 A 的代码.
这一点, 个人代码从 Nim 转译到 TypeScript 就比较头疼,
由于我定义数据结构的访问和判断须要 overload 这些个 array accessing 和 equality,
我一时半会也想不出来 TypeScript 当中能怎么作, 只能用 mutable data 在运行时强行模拟.
没有碰过 Java 跟 C#, 碰过语言当中这套玩法跟 Haskell 却是挺像的,
Haskell 从 class 产生 instance 的时候能够定义一些函数, 就很灵活.
(具体 Haskell type class 高阶玩法真是还玩不起来.)
不过 Nim 相比来讲, 简化是简化了, 但这个语法糖在编码当中就是很方便.
也由于缺失这个功能, 致使我对 Clojure 跟 TypeScript 这都有点不是应该了.
转译代码还发现的问题是因为 JSON 跟 EDN 极为便利,
引发我在大量代码当中直接使用 Array 和 Map 直接表示数据,
这个不能算错, 但数据在 Nim 当中这些都是明确用类型表示的,
也意味着在 Nim 当中有明确的结构进行判断, explicitly...
反观个人 TypeScript 代码, 大量的 Array.isArray
,
而后还有那个不知道怎么说的 typeof any === 'object'
的尴尬,
在类型系统当中使用习惯以后, 回过头感受特别不踏实,
而后我自动跑去折腾 instanceof
的玩法来作对应功能了.
固然, JSON 或者 EDN 通用地表示各类数据, 确实在通用型来讲很是好,
我跨项目调用数据, 这些动态类型就是直接通用的结构,
在 Nim 当中, 通常传递数据是会涉及到一些类型转换, 写写是有点麻烦的.
我不是很能衡量那种方案是更好, 可是对于底层类库, 我是但愿有明确类型的.
TODO