第一章:进入Scheme

经典的第一个程序通常是把一个"Hello world!"显示在控制台上。用你最喜欢的编辑器,创建一个名为hello.scm的文件,并在里面输入以下内容:

  1. ;The first program
  2. (begin
  3. (display "Hello, World!")
  4. (newline))

第一行是一个注释,当Scheme发现一个分号,就把分号和这一行分号后面的文字都忽略了。

begin语句(原文为form)是Scheme用来包括子语句的方式,这个例子里有两个子语句。第一句调用了display过程,该过程会输出它的参数(字符串"Hello, World!")到控制台(或者叫“标准输出”)后面一句调用了newline过程,该过程输出一个换行。

想要运行这个程序首先需要启动Scheme,通常只需要在你操作系统的命令行下面输入你的Scheme可执行程序的名字即可。如果你用的是MzScheme,你需要在操作系统提示符后面输入:

  1. mzscheme

这将调用Scheme listener程序,这个程序读取你的输入,求值,打印结果(如果有的话),然后等待你的下一次输入。由此这通常被称为“读取-求值-打印”的循环。注意这和你操作系统的命令行没有太大区别,操作系统的命令行也读取你的命令,执行,然后等待其他命令。和操作系统一样,Scheme listener有它自己的提示符——通常是>,但也可能是其他的东西。

在Scheme listener里,加载文件hello.scm。直接运行下面的语句即可:

  1. (load "hello.scm")

Scheme现在执行hello.scm文件的内容,输出Hello, World!接着后面是一个换行符。然后你又得到了命令提示符,可以输入更多命令。

现在由于你有一个很好用的listener,所以你用不着每次把你的程序写到一个文件里然后load它,有时候,特别是当你想试试某些东西的时候,直接在listener的提示符后面输入表达式然后看结果会更简单。比如,在Scheme的提示符下输入:

  1. (begin (display "Hello, World!")
  2. (newline))

会得到:

  1. Hello, World!

事实上,你可以简单地在提示符后面输入"Hello, World!"然后你可以得到作为结果的字符串:

  1. "Hello, World!"

因为这是listener对"Hello, World!"求值的结果。

第二种方式产生的结果除了有双引号以外,两段程序还有一个标志性的区别。第一段(用begin开头的)并没有做任何的运算,而显示的结果是displaynewline过程的副作用向标准输出写出来的。第二段程序,"Hello, World!"运算得到的结果在这个情况下和这个字符串本身是一致的。

以后,我们会使用标记=>来表示运算。就像这样E => v表示语句段E 运算得到结果值为v
例如:

  1. (begin
  2. (display "Hello, World!")
  3. (newline))
  4. =>

(没有结果),尽管它有输出Hello, World!到标准输出的副作用。

而另一个程序段,

  1. "Hello, World!"
  2. => "Hello, World!"

在上面两种代码情况下,我们运行完后还是停在命令提示符后。如果要退出Scheme,输入(exit),这样会退出Scheme命令行。

Scheme命令行非常便于交互式的测试程序和程序片段。然而这绝不是必须的。你当然可以坚持传统的方式完全在文件中来创建程序,然后用Scheme来执行它们而不使用任何明显的命令行。

在MzScheme中,例如你可以在操作系统的命令行中这样输

  1. mzscheme r hello.scm

这样不需要和Scheme命令行打交道就可以产生问候的结果了。
在问候结果产生后,mzscheme将会退回操作系统的命令提示。
这几乎就像是你直接写了echo Hello , World!

你甚至可以把hello.scm当成是一个系统命令来看待(一个内核脚本或批处理文件),但具体得等到第十六章来讲解。