像快速失败测试一样运行 SICP 方案文件

发布于 2024-11-28 16:52:09 字数 628 浏览 1 评论 0原文

经过几年的编程,似乎是时候最终攻击SICP了。然而,我不想在 Emacs 中编辑和运行所有内容,而是使用不同的编辑器和简单的 makefile 运行所有练习。这似乎并不完全是规范,因为我找不到任何像运行文件这样基本的参考,直到出现“失败”为止。那么,我如何在shell上运行Scheme,以便它加载一个文件,按顺序计算每个表达式,并在遇到计算结果的语句时立即以非零退出代码终止到 #f 或者如果整个文件被成功评估则退出代码为零? 到目前为止最接近解决方案的事情:

$ cat ch1.scm
...
(= 1 2)
$ scheme --load ch1.scm
...
Loading "ch1.scm"... done

1 ]=>

编辑:换句话说,是否有某种方法可以使如果出现以下情况,则在加载 ch1.s​​cm 期间停止评估其中的表达式的计算结果为#f

After a few years of programming it seems time to finally attack SICP. However, instead of editing and running everything in Emacs, I'd rather use a different editor and a simple makefile to run all the exercises. This doesn't seem to be entirely canon, because I couldn't find any reference to something as basic as running a file until something "fails". So how do I run Scheme on the shell so that it loads a file, evaluates each expression in sequence, and terminates with a non-zero exit code as soon as it encounters a statement which evaluates to #f or with an exit code of zero if the entire file was evaluated successfully? The closest thing to a solution so far:

$ cat ch1.scm
...
(= 1 2)
$ scheme --load ch1.scm
...
Loading "ch1.scm"... done

1 ]=>

Edit: In other words, is there some way to make evaluation stop during the loading of ch1.scm if any of the expressions therein evaluate to #f?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心奴独伤 2024-12-05 16:52:09

如果您不想求助于成熟的单元测试库(可以理解),一种选择是编写自己的单元测试库。您可以使用read从文件中读取s-表达式,使用eval对它们进行评估并测试它们是否为假,然后报告,如果发现错误则退出。像这样的东西应该可以工作:

(define (read-and-test filename env)
  (call-with-input-file
      filename
    (lambda (in)
      (let loop ((input (read in)))
        (if (eof-object? input)
            (display "done!")
            (begin
              (if (eval input env)
                  (begin
                    (display input)
                    (display " ok")
                    (newline)
                    (loop (read in)))
                  (begin
                    (display "failed on ")
                    (display input)
                    (newline)
                    (exit)))))))))

如果将上述内容放入名为 unit.scm 的文件中,并且要测试的文件名为 test.scm,则可以使用以下命令调用它: Unix 命令行中的 MIT 方案如下所示:(

mit-scheme --load `pwd`/unit.scm --eval '(read-and-test "/Users/aki/code/scratch/test.scm" (the-environment))'

注意上面有一些 MIT 方案特定的内容,与 eval 和环境相关)

One option if you don't want to resort to a full-blown unit-testing library (understandable) is to write your own. You can use read to read s-expressions from the file, use eval to evaluate them and test if they are false, and report back, quitting if you find a false. Something like this should work:

(define (read-and-test filename env)
  (call-with-input-file
      filename
    (lambda (in)
      (let loop ((input (read in)))
        (if (eof-object? input)
            (display "done!")
            (begin
              (if (eval input env)
                  (begin
                    (display input)
                    (display " ok")
                    (newline)
                    (loop (read in)))
                  (begin
                    (display "failed on ")
                    (display input)
                    (newline)
                    (exit)))))))))

If you put the above in a file called unit.scm and the file you want to test is called test.scm, you can call this with MIT Scheme from the Unix command line like so:

mit-scheme --load `pwd`/unit.scm --eval '(read-and-test "/Users/aki/code/scratch/test.scm" (the-environment))'

(note there's some MIT Scheme specific things above, related to eval and enviroments)

停顿的约定 2024-12-05 16:52:09

我可以想到两种方法。蛮力方法是编写一个 expect 脚本,该脚本将 schema 作为一个低级进程运行,并一次向其提供一行并检查返回的输出 - 基本上是一个机器人。更优雅的方法是将方案解释器中的顶级 REPL 替换为表达式计算结果为 #f 时退出的 REPL。

I can think of two ways. The brute-force way would be to write an expect script that runs scheme as an inferior process and feeds it a line at a time and checks the returned output -- basically, being a robot. The more elegant way would be to replace the top-level REPL in your scheme interpreter with one that exits if the expression evaluates to #f.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文