Scheme-langserver是一款面向scheme语言的语言服务器,它基于LSP协议(Language Server Protocol)提供了自动补全(auto-complete)、寻找变量定义(goto definition)等功能。
11月21日,scheme-langserver发布了类型推断功能,并将该功能整合进入了自动补全。如图所示,在补全光标处的引导词“l”(大写L)时,scheme-langserver给出了多个可选项,并且将类型匹配程度较高的“length-a”、“length-b”放到了比较靠前的位置——因为“>=”过程(也就是其他语言中的函数)要求变量必须是“real?”,而上文可以推断出“length-a”、“length-b”为“integer?”类型。
这项工作的主要特点在于:
- 使用了作者自行开发的DSL(Domain Specific Language)和解释器实现类型推断功能。这大大降低了编写相关功能的难度,让整个项目的可维护性更强;
- 基于scheme-langserver的面向“未完成代码”的自动补全功能,能够补全局部变量(这在一些竞品中是不能实现的);
- 实现了“渐进定型”实现为动态类型语言的类型推导。关于这一点,可以看如下案例:
例如对于javascript代码,参数a的类型是不清楚的——关于这一点,在typescript当中的解决方法是第二行中的案例——添加类型标注(number)。
function(a){return 1+a}
function(a : number){return 1+a}
但是实际上,我们当然知道“+”操作符操作的只能是“number”(当然还有string等等)。因此,应当由计算机自行推出“a”的类型为“number”而不需要自行推断(当然,这是有一定的代价和其他问题的)。
目前这项工作还存在一些问题,主要包括:
- 类型推断工作使得索引构建时间较长,较大程度影响用户使用体验;
- 类型推断系统引入了一个全排列操作,对于有较多参数(比如4个)的过程(或者说函数)的类型推导造成了限制;
- 还有大量的测试需要进行,以尽可能减少错误;
- 通过一些参数限制了涉及递归函数的类型推断以减少操作间隔感,但是这就在类型推断的可靠性上有了一些问题。
Scheme-langserver同时是“2022中国互联网发展创新与投资大赛公益项目暨2022年中国开源创新大赛”二等奖项目。