跳到主要内容

Scheme 编程语言

· 阅读需 4 分钟

Scheme 是第一门我真正系统学习过的函数式编程语言。Scheme 语言的标志是一个 Lambda 字符“λ”,一眼就可以看出这门语言的出处。Scheme 是 LISP 语言的两大方言之一,而 LISP 又是人类开发出的第二款高级编程语言(第一个是 FORTRAN)。

因为太古老,Scheme 的编程思路和现在常见的语言差距还是非常大的。我刚开始接触 Scheme 时的困惑不亚于刚接触 LabVIEW。Scheme 的语法定义是比较简单的,比时下流行的编程语言都简单得多,但毕竟也是一门完整编程语言,不可能写一小段就介绍全面,这里就只能介绍一些最基本功能了。

Scheme 直观上最明显的特点是括号多,它的所有数据(比如列表)和程序结构(比如函数、判断语句)等都被包裹在括号内,因此,一段代码里会有数不清的层层括号。在编程思想上的最大特点就是函数式编程。再 Scheme 程序中,一切都是函数。

在 Scheme 中写 Hello, world 的代码如下: (display "Hello, World!")

在这段中 display 是一个函数,用于在屏幕上打印文字,而后面的字符串则是 display 的参数。单这一句,与常见编程语言的用法差距也不算太大。

在 Scheme 语句中,函数名总是要放在参数之前,运算符也是一个函数。所以,如果要计算 “2+3”,写出来的程序是这样的: (+ 2 3) 。 Scheme 的函数很多是可以跟多个参数的,比如 (max 2 6 3) 或者 (+ 6 4 8) 等等。如果是一组数据,比如一个 list,那么就在括号前加个单引号,比如 '(a b c d),这就不再是函数调用,而是一个列表了。

函数的定义一般类似如下:(lambda (x) (+ x 2))。lambda 是关键字,后面跟着函数参数,在后面是函数体。在 Scheme 语句中使用关键字 define 给常量命名,使用关键字 let 给变量命名。函数也可以是一种变量,比如下面的语句就给了新定义的函数一个名字“square”:

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

Scheme 语言还有一特点就是没有循环,所有需要循环的地方都要使用递归来完成。这和早期的 LabVIEW 正相反,早期的 LabVIEW 不支持递归,所有要用到递归的地方都必须转换成循环。比如,在 Scheme 中计算阶乘,只能采用递归的形式:

(define factorial (lambda (n) (if (= n 0) 1 (* n (factorial (- n 1))))))

我在学习 Scheme 的过程中,最大的收获是把递归彻底弄清楚了。递归有时候还是比较容易绕的,比如把一个列表从头开始归并,和从尾开始归并要采用不同的递归策略。以前都没有深入考虑过,学习了 Scheme 才真正系统的研究清楚了。