2.1 同Scheme交互

大多数 Scheme 系统提供了一个交互式的编程环境,极大地简化了程序开发与试验。一个最简单的交互环境叫做 "read-evaluate-print-loop",简称 repl。它读取你输入的每一个表达式,并对它求值,然后返回结果。

在一个交互式 Scheme 系统里,你可以从键盘输入一个表达式,并且立刻看到它的结果。你可以定义一个函数,将它应用到具体的参数上,观察它如何工作。你甚至可以输入包含着多个函数定义的一整个程序,并且直接测试它。当你的程序变得越来越长,你可以将它保存在一个文件当中,然后在 Scheme 里载入它,然后就可以交互地测试它。在大多数 Scheme 系统里,可以通过非标准的 load 过程来载入一个文件,它接受一个字符串形式的文件名作为参数。将你的程序写进一个文件有几个好处:你有机会更仔细地编写程序,你可以改正错误而不需要重新输入整个程序,你可以保存以一个拷贝以便将来使用。大多数 Scheme 实现将载入保存在文件中的表达式视为与你从键盘输入等价。

另外,Scheme 提供了各种输入输出过程,REPL 接手了怎么读取表达式以及怎么输出值的工作,这样就可以将精力集中在怎么写程序上,不用为怎么显示结果操心。

本书中的示例代码遵循一个简单的规则,首先给出你可能需要从键盘输入的表达式,表达式也许会跨越多行。而表达式的返回值跟随在符号“ => ”后面,读作“求值为”。当输入一个定义(define),或者表达式的值为未定义时省略 "=>" 符号。

示例代码按照一种“好看”的格式书写,代码容易阅读,因为每一个表达式及子表达式的关系清晰可见。没有哪一种风格是标准的,重要的是建立一种风格,并一直使用它。

如果你可以访问一个交互式 Scheme 系统,现在打开它并输入你读到的代码会是个不错的主意。一个最简单的 Scheme 表达式是一个字符串常量。尝试在提示符后面输入 "Hi Mom!" (包括双引号在内),然后敲回车,系统会回应同样的 "Hi Mom!"; 一个常量的值就是它自己。

"Hi Mom!" => "Hi Mom!"

下面是一个表达式集合,以及它们的返回值。本章后面的部分会解释它们,不过,现在请尝试输入它们,练习与 Scheme 交互。

"hello" => "hello"
42 => 42
22/7 => 22/7
3.141592653 => 3.141592653
+ => #<procedure>
(+ 76 31) => 107
(* -12 10) => -120
'(a b c d) => (a b c d)

小心不要丢掉任何单引号('), 双引号("),或者括号。

下面是更多的表达式,你可以尝试自己揣摩它们的意思,或者看完本章你就知道了。

(car '(a b c)) => a
(cdr '(a b c)) => (b c)
(cons 'a '(b c)) => (a b c)
(cons (car '(a b c))
      (cdr '(d e f))) => (a e f)

如你所见,Scheme 表达式可以跨越多行。Scheme 系统可以识别出没有闭合的双引号,括号。

下面,我们尝试定义一个函数

(define square
  (lambda (n)
    (* n n)))

这个函数计算 n 的平方。define 建立一个新的变量绑定,lambda创建了一个函数,*是乘法函数的名字。注意这些表达式的形式。所有结构形式包含在括号里面,并且写作“前缀”形式,即,操作符写在参数前面。如你所见,这是真的,即使是最简单的算术运算,比如 *.

尝试使用刚刚定义的 square 函数

(square 5) => 25
(square -200) => 40000
(square 0.5) => 0.25
(square -1/2) => 1/4

尽管下面的定义很短,你也可以将它输入一个文件,假设文件名叫做 "reciprocal.ss"

(define reciprocal
  (lambda (n)
    (if (= n 0)
        "oops!"
        (/ 1 n))))

reciprocal 函数计算 n 的倒数,返回 1/n,如果 n == 0,则返回一个字符串 "oops!"

现在,回到 Scheme 中,尝试载入刚才的文件

(load "reciprocal.ss")

最后,尝试使用我们刚刚定义的函数

(reciprocal 10) => 1/10
(reciprocal 1/10) => 10
(reciprocal 0) => "oops!"
(reciprocal (reciprocal 1/10)) => 1/10

results matching ""

    No results matching ""