Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
– Antoine de Saint-Exupéry
通过包管理器下载 mit-scheme
MacOS:
brew install mit-scheme
Ubuntu:
sudo apt-get update
sudo apt-get install mit-scheme
REPL 基本使用
(REPL: Read-Evaluate-Print Loop)
-
进入 REPL:
mit-scheme
-
在 REPL 加载中加载 scheme 代码:
1 ] => (load "path/to/file.scm")
(后缀
.scm
可以省略.) -
查看手册:
-
man mit-scheme
命令行查看 mit-scheme CLI 手册, 很简短, 可以通过命令行参数指定堆栈大小 / 加载文件 / 同时打开编辑器/ … -
按下 Ctrl-C 后键入
H
查看中断手册:-
Ctrl-C: 接收下一个键盘输入, 决定中断行为.
-
Ctrl-G: 回到 top-level
-
Ctrl-Z: 挂起当前 mit-scheme 进程
-
-
按下 Ctrl-C 后键入
?
查看手册: 下一键盘输入 (option) 与 REPL 行为 (清屏 / 挂起 / 退出 / 忽略中断 / …) 的对应关系;
-
-
如果 REPL 没有反应:
-
检查括号是否逐对匹配;
-
Ctrl-C 中断后回到 REPL, 提示符 (
1 ] =>
/2 error>
) 不会重新显示. -
担心递归太深? 递归深度超限时, REPL 会提示
Recursion depth limit exceeded. Aborting!
(3.1 中提到可以通过 CLI 参数指定堆栈大小, 即, mit-scheme使用的堆栈资源是有限的.)
-
-
ScHeMeScheme 是大小写不敏感的语言.所以
(LoAd "path/to/file.scm")
/(DEFINE x 1)
/(define x 1)
/(defiNE x 1)
/… 都不会引发错误. -
History variable (procedure): 重用 REPL 求值后返回的 procedure:
1 ]=> (average-dump square) ;Value: #[compound-procedure 12] ; 可以在后续表达式中重用, 就像 gdb 中的 history variable `$1` 1 ]=> (#[compound-procedure 12] 10) ; 虽然也不是很方便直接使用, 但是确实是能用 ;Value: 55 1 ]=> (define newfunc #[compound-procedure 12]) ; 可以绑定到一个标识符上, 再复用 ;Value: newfunc 1 ]=> (newfunc 10) ;Value: 55
后记
不知道是否有更好用的 Scheme REPL,这个 REPL 确实是比较原始,不支持历史表达式的回溯,不支持光标移动,但是一想到 lisp 历史这么悠久,语法本身十分简洁纯净,我就接受了一切。(不像写 Haskell 的时候 LSP 出了问题,我必通过重启 VSCode / 重启电脑 / 更改 LSP 版本先把 LSP 重新拉起来,而不是先把代码写了。)