【发布时间】:2015-04-22 00:32:23
【问题描述】:
我正在尝试实现一个数据结构来保持程序的状态(变量绑定)。我用关联列表表示状态,关联列表是键值对列表。
一个示例关联列表是:'((x . 3) (y . (1 2)) (z . a))。在此示例中,键 'x 的值是 3,'y 的值是 '(1 2),'z 的值是 'a。
为了操纵状态,我有两个函数:
-
(get-binding state var)此函数返回值符号 var 绑定(分配)到状态。
-
(set-binding state var val)此函数返回一个与 state 相同的新状态,不同之处在于 var 绑定到 val。
-
empty-state此变量对应于没有绑定的状态。它是使用define定义的。 注意:empty-state 不是函数。
例子:
> (get-binding (set-binding (set-binding empty-state 'x 3) 'x 4) 'x)
输出4。
这是我的代码:
(define (enclosing-environment env) (mcdr env))
(define empty-state null)
(define (get-binding env var)
(define (env-loop env)
(define (scan vars vals)
(cond [(null? vars)
(env-loop (enclosing-environment env))]
[(eq? var (mcar vars))
(mcar vals)]
[else
(scan (mcdr vars)
(mcdr vals))]))
(if (eq? env empty-state)
(error "Unbound variable:" var)
(let ([frame (first-frame env)])
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
(define (set-binding! env var val)
(define (env-loop env)
(define (scan vars vals)
(cond [(null? vars)
(env-loop (enclosing-environment env))]
[(eq? var (mcar vars))
(set-mcar! vals val)]
[else
(scan (mcdr vars)
(mcdr vals))]))
(if (eq? env empty-state)
(error "Unbound variable -- SET!:" var)
(let ([frame (first-frame env)])
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
但它给出了一个错误,显示“未绑定变量 -- SET!: x”。如何预防?
【问题讨论】:
-
使用哈希映射而不是可变关联列表会容易得多。
-
...事实上,你为什么要使用可变对呢?在我看来
get-binding和set-binding是纯粹的函数操作。 -
嘿,我记得 Racket 的主要开发人员之一提到他不确定在 Racket 中包含可变对毕竟是一个好举措。
-
我们能不能把重点放在这里,伙计们?
-
set-binding的描述与您的实现不匹配。set-binding!正在改变一个绑定,如果一个存在(任何地方),否则抛出一个错误。这与返回“与状态相同的新状态,但 var 绑定到 val 除外”不同。
标签: binding scheme environment-variables racket state