在Scheme 中,您正在使用let 进行本地绑定,隐藏更高级别的内容。由于+ 和* 只是碰巧对过程求值的变量,因此您只是给旧过程提供了其他变量名称。
(let ((+ *))
+)
; ==> #<procedure:*> (non standard visualization of a procedure)
Scheme 中没有保留字。如果您查看其他语言,保留字的列表非常高。因此在 Scheme 中你可以这样做:
(define (test v)
(define let 10) ; from here you cannot use let in this scope
(define define (+ let v)) ; from here you cannot use define to define stuff
define) ; this is the variable, not the special form
;; here let and define goes out of scope and the special forms are OK again
(define define +) ; from here you cannot use top level define
(define 5 6)
; ==> 11
这样做的真正好处是,如果您选择了一个名称,而标准的下一个版本恰好使用相同的名称来表示类似但不兼容的东西,您的代码不会中断。在我使用过的其他语言中,新版本可能会引入冲突。
R6RS 让一切变得更简单
从 R6RS 我们有库。这意味着我们可以完全控制我们从标准中获得哪些顶级表格到我们的程序中。你有几种方法可以做到:
#!r6rs
(import (rename (except (rnrs base) +) (* +)))
(+ 10 20)
; ==> 200
这也可以。
#!r6rs
(import (except (rnrs base) +))
(define + *)
(+ 10 20)
; ==> 200 guaranteed
最后:
#!r6rs
(import (rnrs base)) ; imports both * and +
(define + *) ; defines + as an alias to *
(+ 10 20)
; ==> 200 guaranteed
其他语言也这样做:
JavaScript 可能是最明显的:
parseFloat = parseInt;
parseFloat("4.5")
// ==> 4
但你不能碰他们的运营商。它们被保留是因为语言需要为运算符优先级做很多事情。就像 Scheme JS 是鸭子打字的好语言一样。