Replies: 1 comment 1 reply
-
我可以给你推荐 type checker 的学习材料 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
目标
首先 Calcit 是模仿 ClojureScript, 虽然是动态类型, 但是提供一些简单的检查,
ClojureScript 当中做的检查是不少, 尽管依然是动态类型..
https://clojurescript.org/reference/compiler-options#warnings
往远了说, 参考 Elm 的设计思路, 及早发现类型问题, 对热替换过程的保证就更为可靠,
https://elm-lang.org/news/interactive-programming
问题所在的局部
目前 Calcit 提供的主要是动态处理的
arguments.length
的检查, 实现比较容易,以及执行代码前, 在预处理阶段, 检查函数和局部变量是否存在.
对于类型, 完全没有检查, 全都依靠运行时动态去处理.
短期还是可以接受的, 毕竟糊页面的时候类型出错还算少, 大部分都只是展示用,
不过随着 #44 引入 methods, 引发了新的问题.
由于 methods 是动态调用实现的, 意味着预处理过程无法检查.
作为例子,
如果是函数, 目前通过判断 local scope 当中是否存在, 然后判断 namespace 是否存在,
也会涉及到在 imports 当中查找, 对应到其他的 namespace 中是否存在, 这个步骤没有障碍.
但如果是一个方法在调用的时候, a 就是跟值相关了,
目前如果 a 可以被调用, 那么其结构就就应该是个 Tuple
(:: klass va)
, 或者一个内置类型同样找对内置的klass
,然后
klass
要求是一个 Record, 其中包含一个 field 为.to-list
.目前希望的就是检查到这一步为止, 至于具体的 method 的函数类型甚至函数参数和结果, 暂时可以不检查.
由于 Lisp 语法树, 存在变量,
if
let
甚至进一步的函数调用, method 调用,类型的传递就会涉及到相当多的操作, 基本上相当于整个语言加简化的 type checker 了.
初步的步骤我有模糊的理解. 具体实现细节想不清楚.
初步思路
我这边是要考虑跟 Cirru 这边的工具达成契合... 因为 Calcit 本身已经基于 Cirru.
那么先需要是在已有 S 表达式当中加入类型提示, 而不是换掉 Cirru 去用 Haskell 系的语法,
初步的思路, 可以在函数体当中增加标识来作为类型提示,
以及用
guard-type
在表达式内部, 做一定的类型约束和检查(动态静态均不同程度实现一些识别),Calcit 如果加入类型, 还是以辅助快速发现低级错误为主, 其次在运行时辅助检查,
对于提供详细类型信息用于生成 VM bytecode, 只能作为远期的目标了.
并且解释时为了热替换方便不宜做费时的检查, 而生成 bytecode 显然顺需要做深层甚至费时的分析检查.
暂时参照 Calcit 已有类型, 笼统地提供一些类型标记:
后续可以尝试往复合的类型结构延伸,
不过在 Calcit 解释器内部估计还是参照 Clojure Spec 的方式动态插入检查,
对应 VM 需要的静态的类型, 只能尝试以语言子集的方式, 由外部编译器基于预处理后的 IR 进行.
其他
该草案目前还在设想阶段.
Beta Was this translation helpful? Give feedback.
All reactions