Vector 方案向量集的实现
我正在努力理解向量集是如何设置的代码>已实现。在我看来,它就像Vector 方案向量集的实现,vector,scheme,sicp,Vector,Scheme,Sicp,我正在努力理解向量集是如何设置的已实现。在我看来,它就像向量集是一种特殊的形式-很像集合是。当我看使用向量集的示例时我看到以下令人满意的行为(诡计) 我也可以这样做(诡计) 与设置形成对比行为: (define a 1) (define test2 (lambda b (begin (set! b 0) b))) (test2 (quote a)) $26 = 0 a $27 = 1 在这种情况下,据我所知,集合将b更改为0(而不是“已评估的”b(应该是a)。上面的eval技巧在这里不起作用
向量集
是一种特殊的形式-很像集合代码>是。当我看使用向量集的示例时代码>我看到以下令人满意的行为(诡计)
我也可以这样做(诡计)
与设置形成对比代码>行为:
(define a 1)
(define test2 (lambda b (begin (set! b 0) b)))
(test2 (quote a))
$26 = 0
a
$27 = 1
在这种情况下,据我所知,集合代码>将b
更改为0(而不是“已评估的”b
(应该是a
)。上面的eval
技巧在这里不起作用
我的问题是:vector set!
与set!
(或)相比是如何实现的。vector set!
是在它的第一个参数处达到峰值的吗?还是其他什么?我试着看了一些方案实现,但从代码中提取要点是很棘手的。也许有人有解释或链接到一些(sicp风格)方案实现。函数向量集!
是一个所谓的原语。
它是一个函数(不是特殊形式),但必须在运行时内实现
注意:特殊表单是使用与正常应用程序中使用的顺序不同的评估顺序的表单。因此,if
、cond
、或
等都是特殊表单
有些实现(我不记得Guile是否是其中之一)有一个函数primitive?
,可用于测试函数是否为primitive
> (primitive? vector-set!)
#t
在“某些SICP风格的方案实施”中,vector set!
将由eval vector mutation
处理,它可能是
(define (eval-vector-mutation exp env)
; exp = (vector-set! vec idx val)
(let ((vec (eval (vector-mutation-vec exp) env))
(idx (eval (vector-mutation-idx exp) env))
(val (eval (vector-mutation-val exp) env)))
(begin
(set-car! (cddr (drop vec idx)) val) ; srfi-1 drop
vec)))
和使向量
由
(define (eval-vector-creation exp env)
; exp = (make-vector cnt val)
(let ((cnt (eval (vector-creation-cnt exp) env))
(val (eval (vector-creation-val exp) env)))
(cons 'vector ; tagged list
(cons cnt ; vector size
(make-list cnt val))))) ; srfi-1 make-list
在这里,向量由底层方案实现中的标记列表表示(不是所定义的方案),以及它的变异原语,如set car!
,用于操纵它们。如果您的实现语言是C,比如说,您只需要使用C数组作为向量表示,或者可能是一个将数组与其他相关信息(如大小等)耦合的结构。谢谢。您可能不知道我可以查看的参考-I a我在寻找一些简单的东西。我对向量集!
是如何实现的还不清楚-我应该从它是一个原语的事实中派生出一些东西吗?除了向量集!
之外,可能还有其他原语显示了我可以看到的类似行为?我的理解正确吗vector set!
不是一种特殊的形式,它的第一个参数(v
)是经过计算的,而不是像set!
那样自动引用的。下面展示了向量是如何被vector set!
修改的内部数据结构
(define (eval-vector-mutation exp env)
; exp = (vector-set! vec idx val)
(let ((vec (eval (vector-mutation-vec exp) env))
(idx (eval (vector-mutation-idx exp) env))
(val (eval (vector-mutation-val exp) env)))
(begin
(set-car! (cddr (drop vec idx)) val) ; srfi-1 drop
vec)))
(define (eval-vector-creation exp env)
; exp = (make-vector cnt val)
(let ((cnt (eval (vector-creation-cnt exp) env))
(val (eval (vector-creation-val exp) env)))
(cons 'vector ; tagged list
(cons cnt ; vector size
(make-list cnt val))))) ; srfi-1 make-list