Scheme 是一种极简主义的 Lisp 编程语言方言,旨在促进函数式编程风格,同时推广简单而清晰的语法。它的特点是使用括号、强大的宏系统,以及对递归和一等过程的强烈强调。该语言鼓励函数式编程范式,并支持多种编程技术,包括函数式、命令式和逻辑编程。
Scheme 于 1970 年代由麻省理工学院(MIT)的 Gerald Jay Sussman 和 Guy L. Steele Jr. 创建。它的开发旨在简化和改进原始的 Lisp 语言,因为后者随着时间的推移变得复杂。Scheme 的动机是创建一种更易于实现和教授的语言,同时仍然足够强大以表达复杂的思想。
多年来,Scheme 经历了各种修订和标准化努力。其中最著名的标准是 RnRS(修订n 报告算法语言 Scheme),它正式化了该语言及其特性。此后,Scheme 社区继续发展该语言,导致了更新的标准,如 R6RS 和 R7RS,这些标准引入了新特性和改进。
截至目前,Scheme 在学术环境中仍然受到欢迎,特别是在计算机科学教育中,因其优雅和清晰的语法。它的影响可以在许多现代编程语言和范式中看到。Scheme 通常与函数式编程社区相关联,并激发了如 Clojure 和 Racket 等语言,这些语言在其原则的基础上扩展了其能力。
Scheme 使用完全的括号语法,代码以前缀表示法书写;例如,加法操作写作 (+ 1 2)
。
Scheme 中的函数是一等公民,这意味着它们可以作为参数传递或从其他函数返回。示例:
(define (make-adder x)
(lambda (y) (+ x y)))
(define add5 (make-adder 5))
(add5 10) ; 返回 15
Scheme 支持尾调用优化,允许函数在尾位置的递归调用重用当前的栈帧,从而防止栈溢出。
Scheme 允许使用继续,程序员可以捕获当前的计算状态并操控控制流:
(call-with-current-continuation
(lambda (exit)
(exit 'done)))
Scheme 具有强大的宏系统,允许程序员创建语法扩展。一个简单的宏可以定义如下:
(define-syntax my-if
(syntax-rules ()
((_ test then else)
(if test then else))))
Scheme 通过列表、对和高阶函数等结构支持数据抽象,使得数据的高效操作成为可能。
Scheme 采用词法作用域,变量的作用域由其在源代码中的物理位置决定。这导致了关于变量绑定的可预测行为。
Scheme 是动态类型的,允许变量持有任何类型的值,而无需显式的类型声明。
作为 Lisp 方言,Scheme 针对列表处理进行了优化,使得对列表进行操作变得简单:
(define my-list (list 1 2 3 4))
(car my-list) ; 返回 1
(cdr my-list) ; 返回 (2 3 4)
Scheme 函数可以以尾位置递归定义,以优化内存使用和性能。例如:
(define (factorial n)
(define (fact-helper n acc)
(if (zero? n)
acc
(fact-helper (- n 1) (* n acc))))
(fact-helper n 1))
Scheme 应用程序通常可以使用所选实现的运行时环境构建。例如,在 Racket 中,可以使用命令行工具 racket
来运行 .rkt
文件或将其编译为可执行文件。
有多种编译器和解释器可用于 Scheme,包括:
Scheme 在学术界广泛用于教授编程原理,并作为计算机科学研究的工具。它在人工智能、语言设计和脚本编写等领域有应用,以及在需要符号计算或复杂数据操作的各种领域。
这两种语言都支持函数式编程风格,但 Python 强调可读性和简单性,而 Scheme 则专注于强大而简洁的表达。Scheme 的括号重语法可能被视为初学者的障碍,而 Python 的基于缩进的语法通常更易于接触。
JavaScript 也支持函数式编程,并具有一等函数。然而,JavaScript 具有基于原型的对象系统,而 Scheme 则依赖于函数式范式。Scheme 的宏系统提供了 JavaScript 中不存在的能力。
C 是一种低级的、静态类型的语言,旨在进行系统编程,而 Scheme 是高级的、动态类型的。C 关注性能和硬件级别的操作,而 Scheme 强调抽象和计算的理论方面。
这两种语言都根植于函数式编程。Haskell 使用更严格的类型系统并支持惰性求值,而 Scheme 的动态类型和急切求值允许更灵活的编程,代价是某些性能。
Ruby 是一种面向对象的编程语言,混合了函数式编程特性,而 Scheme 是纯函数式的。Ruby 的语法更冗长,而 Scheme 的简洁性源于其极简设计。
将 Scheme 代码翻译为其他语言可以通过理解 Scheme 语法和目标语言的工具来促进。一些有用的源到源代码翻译工具包括:
Chicken Scheme 提供一个编译器,可以将 Scheme 代码翻译为 C,从而能够利用 C 库并创建高效的可执行文件。
Racket,作为 Scheme 的衍生物,具有内置的能力,可以将代码转换和编译为 JavaScript,使得部署 Web 应用程序变得更容易。
Gambit Scheme 可以将 Scheme 代码编译为 C 和本地可执行文件,为性能关键的应用程序提供高效的翻译选项。