将符号定义为其他东西时,scheme 中发生了什么?
What happened in scheme when defining a symbol to be something else?
我是 Scheme 语言的初学者。
最近发现数据类型symbol可以用引号显示,像这样:
> 'E
E
> (quote E)
E
但是,如果执行下面的代码,每一种引用都可能失败:
> (define 'E 123)
> 'E
E: undefined;
cannot reference an identifier before its definition
> 'abc
abc: undefined;
cannot reference an identifier before its definition
那么当代码 (define 'E 123)
被执行时发生了什么?
首先你要求 Scheme 计算 (define 'E 123)
。让我们在它前面加一个引号,看看没有 '
shorthand 会是什么样子。你总是可以这样做:引用任何表达式来询问 Scheme,“你认为这个值是多少?”
> '(define 'E 123)
=> (define (quote E) 123)
嗯,在 Scheme 中,(define (x ...) ...)
是 (define x (lambda (...) ...))
的 shorthand:它只是一个方便的 shorthand 来定义一个函数。所以在这种情况下 (define (quote E) 123)
与 (define quote (lambda (E) 123))
相同。因此,您要重新定义的符号是 quote
,并且您将其定义为一个参数的函数,该参数始终为 returns 123.
接下来您要求评估 'E
。让我们再次扩展它以查看 shorthand:
> ''E
=> (quote E)
您现在调用您定义的 quote
函数,并将变量 E
作为参数传递给它。但是 E
以前没有定义过,所以失败了。如果你愿意,你可以先定义 E
为任何值,然后 'E
可能会 return 123。这取决于你使用的是什么 Scheme 评估器:我找到的那个当您尝试重新定义 quote
时并不太感激它,但显然您并不介意,所以我怀疑您会得到 123,并且如果您定义 abc
然后求值,您会得到相同的结果'abc
.
一般来说(define name ...)
是在(bind name)
作用域的开头进行转换,在define
出现的地方执行(set! name ...)
。您需要定义一个符号,而不是 (quote name)
。因为define
是一种特殊的形式,求值规则是特殊的,不是一般的应用——define
不是函数调用。
我是 Scheme 语言的初学者。
最近发现数据类型symbol可以用引号显示,像这样:
> 'E
E
> (quote E)
E
但是,如果执行下面的代码,每一种引用都可能失败:
> (define 'E 123)
> 'E
E: undefined;
cannot reference an identifier before its definition
> 'abc
abc: undefined;
cannot reference an identifier before its definition
(define 'E 123)
被执行时发生了什么?
首先你要求 Scheme 计算 (define 'E 123)
。让我们在它前面加一个引号,看看没有 '
shorthand 会是什么样子。你总是可以这样做:引用任何表达式来询问 Scheme,“你认为这个值是多少?”
> '(define 'E 123)
=> (define (quote E) 123)
嗯,在 Scheme 中,(define (x ...) ...)
是 (define x (lambda (...) ...))
的 shorthand:它只是一个方便的 shorthand 来定义一个函数。所以在这种情况下 (define (quote E) 123)
与 (define quote (lambda (E) 123))
相同。因此,您要重新定义的符号是 quote
,并且您将其定义为一个参数的函数,该参数始终为 returns 123.
接下来您要求评估 'E
。让我们再次扩展它以查看 shorthand:
> ''E
=> (quote E)
您现在调用您定义的 quote
函数,并将变量 E
作为参数传递给它。但是 E
以前没有定义过,所以失败了。如果你愿意,你可以先定义 E
为任何值,然后 'E
可能会 return 123。这取决于你使用的是什么 Scheme 评估器:我找到的那个当您尝试重新定义 quote
时并不太感激它,但显然您并不介意,所以我怀疑您会得到 123,并且如果您定义 abc
然后求值,您会得到相同的结果'abc
.
一般来说(define name ...)
是在(bind name)
作用域的开头进行转换,在define
出现的地方执行(set! name ...)
。您需要定义一个符号,而不是 (quote name)
。因为define
是一种特殊的形式,求值规则是特殊的,不是一般的应用——define
不是函数调用。