为何未重定义常量的Racket代码会报重定义常量错误?
Racket中"重定义常量"错误的原因解析
首先看触发错误的代码:
#lang racket (define foo1234 (call/cc (lambda (j) (j (lambda (_) (j 5)))))) (foo1234 (lambda (_) 2))
运行后抛出的错误信息:
define-values: assignment disallowed;
cannot re-define a constant
constant: foo1234
in module:"/Users/mheiber/one.rkt"
错误本质
这个错误的核心是**call/cc的延续(j)绑定到了模块顶层define foo1234的赋值操作**,具体过程:
- 执行
(j (lambda (_) (j 5)))时,延续j会直接把这个lambda作为foo1234的初始值,模块继续执行到调用(foo1234 ...)。 - 调用
foo1234时,会执行(j 5)——此时的j是模块初始化阶段用来给foo1234赋值的延续。这相当于尝试把5重新赋值给已经被定义为不可变常量的foo1234,而模块顶层define定义的变量默认是不可变的,因此触发"无法重定义常量"的错误。
你没有显式写重定义代码,但延续的二次调用间接触发了对常量的赋值操作,这就是错误的来源。
内容的提问来源于stack exchange,提问作者Max Heiber
相关产品推荐
相关产品推荐

