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
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
目标
首先 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