scheme-langserver

类型推断子系统评估报告

评估工具:bin/output-type-analysis.ss 单库模式
评估对象:scheme-langserver 自身 library
运行时间:2026-06-18
代码基线:kimi 分支,PRIVATE-MAX-DEPTH 保持原值 10PRIVATE-MAX-RESULTS = 500 结果数量预算


1. 执行摘要

本次评估按 task.md 的规划,对 6 个复杂度递增的 library 逐个运行类型推断。调试过程中发现 util/containutil/binary-search 因递归函数类型推断结果无限膨胀而超时。最终采用结果数量预算方案:在 analysis/type/domain-specific-language/interpreter.slstype:interpret 中,当单步结果列表去重后超过 PRIVATE-MAX-RESULTS(200)时,只保留前 200 项。PRIVATE-MAX-DEPTH 保持原来的 10 不变。

Library 运行结果 输出大小 说明
(scheme-langserver util json) ✅ 完成 213 B 2 个标识符,全部保守推断
(scheme-langserver virtual-file-system file-node) ✅ 完成 2.1K 16 个标识符,record 相关识别较好
(scheme-langserver analysis identifier reference) ✅ 完成 7.2K 32 个标识符,union 爆炸被预算截断
(scheme-langserver analysis type domain-specific-language interpreter) ✅ 完成 8.8K 15 个标识符,核心递归函数结果在 200 项处截断
(scheme-langserver util contain) ✅ 完成 3.6K contain?ordered-contain? 均有输出
(scheme-langserver util binary-search) ✅ 完成 2.1K binary-search 有输出

总体结论


2. 逐库结果统计

Library Export 数量 有类型输出的标识符 类型输出条数 something? 占比(近似) 明显错误
util/json 2 2 2 100% 0
virtual-file-system/file-node 16 14 21 ~95% 0
analysis/identifier/reference 32 27 62 ~95% 0
analysis/type/interpreter 15 14 75 ~99% 0
util/contain 2 2 30 ~95% 0
util/binary-search 1 1 20 ~95% 0

说明:


3. 典型案例分析

3.1 virtual-file-system/file-node: make-file-node — 较好案例

源码:

(define-record-type file-node ...)

推断类型:

([identifier-reference file-node?] <- (inner:list? something? ... ) )

点评:

3.2 virtual-file-system/file-node: file-node-children — 过度保守

源码:

(define file-node-children
  (record-accessor file-node-type 4))

推断类型:

(something? <- (inner:list? [identifier-reference file-node?] ) )

点评:

3.3 util/json: read-json — 完全保守

源码:

(define (read-json string)
  (json-read (open-input-string string)))

推断类型:

(something? <- (inner:list? something? ) )

点评:

3.4 analysis/identifier/reference: meta? — 精确的 predicate 被保留

源码:

(define (meta? identifier)
  (not (null? (identifier-reference-top-environment identifier))))

推断类型:

([identifier-reference boolean?] <- (inner:list? [identifier-reference identifier-reference?] ) )

点评:

3.5 util/binary-search: binary-search — 结果被截断但不再超时

推断类型(节选):

(something? <- (inner:list? something? (something? <- (inner:list? something? something? ) ) something? [identifier-reference integer?] [identifier-reference integer?] ) )
(something? <- (inner:list? something? something? something? [identifier-reference integer?] [identifier-reference integer?] ) )
...

点评:

3.6 analysis/type/interpreter: type:interpret — 结果被截断

推断类型(节选):

(something? <- (inner:list? [identifier-reference index-node?] something? (inner:list? something? ... ) [identifier-reference real?] ) )
...

点评:


4. 发现的问题清单

4.1 中等

  1. 复杂递归函数类型组合爆炸
    • 影响库:util/containutil/binary-searchanalysis/type/interpreter
    • 现象:不截断时会产生数万条签名并超时。
    • 当前缓解:结果数量预算(200 项)截断,避免超时,但输出仍较冗长。
  2. record accessor/setter 类型不精确
    • 影响库:virtual-file-system/file-node
    • 现象:file-node-childrenfile-node-document 等 getter 返回 something?
    • 原因:record-accessor / record-mutator 的类型规则未与 define-record-type 的字段定义联动。

4.2 轻微

  1. 简单函数过度保守
    • 影响库:util/jsonutil/containutil/binary-search
    • 现象:参数和返回均为 something?
    • 原因:涉及字符串/IO/递归的函数缺乏精确规则。
  2. 输出可读性差
    • inner:list?inner:pair? 等内部类型表示对人类阅读不够友好。

5. 改进建议

按投入产出比排序:

  1. 增强 record 类型规则(中优先级)
    • record-accessor / record-mutator 能从 define-record-type 的字段定义中获取字段类型。
    • 这能提升 virtual-file-system/file-node 等库的 getter/setter 精度。
  2. 类型推断阶段的 union 合并/简化(中优先级)
    • 在推断阶段合并参数结构相同、仅返回不同的函数类型。
    • 这能显著减少 analysis/identifier/reference 等库的签名数量。
  3. 为常用 IO/字符串函数添加规则(低优先级)
    • read-jsongenerate-json 等可保守地标记为 (something? <- (inner:list? [identifier-reference input-port?]))
    • 但这类规则收益有限,且容易过拟合。

6. 阈值调优实验(2026-06-20 更新)

为确定 PRIVATE-MAX-RESULTS 的最优值,对 100 / 200 / 500 / 1000 四个阈值进行了对比实验。实验脚本为 bin/benchmark-max-results.sh,对每个阈值运行 bin/output-type-analysis.ss 的 6 个目标 library,记录 wall-clock 时间和输出行数。

6.1 实验结果

Library 100 200 500 1000
(scheme-langserver util contain) 67.74 s / 24 行 70.81 s / 24 行 71.74 s / 24 行 70.58 s / 40 行
(scheme-langserver util json) 49.65 s / 6 行 49.82 s / 6 行 52.36 s / 6 行 ~35443 s / 6 行
(scheme-langserver virtual-file-system file-node) 51.13 s / 39 行 49.57 s / 39 行 54.50 s / 39 行
(scheme-langserver analysis identifier reference) 52.14 s / 92 行 51.46 s / 96 行 54.48 s / 99 行
(scheme-langserver analysis type domain-specific-language interpreter) 50.11 s / 66 行 52.67 s / 88 行 54.98 s / 89 行
(scheme-langserver util binary-search) 54.50 s / 19 行 59.89 s / 19 行 58.35 s / 19 行

6.2 结论

7. 已知限制说明


8. 本次变更


9. 交付物