我想了解vector-set!
的实施方式。在我看来,vector-set!
是一种特殊的形式 - 就像set!
一样。当我使用vector-set!
查看示例时,我会看到以下所需的行为(在guile中)。
(define test (lambda (v i) (vector-set! v i 0)))
(define v (make-vector 5 1))
v
$1 = #(1 1 1 1 1)
(test v 0)
v
$2 = #(0 1 1 1 1)
我也可以这样做(在诡计中)
(define test (lambda (v i) (vector-set! (eval v (interaction-environment)) i 0)))
(test (quote v) 3)
v
$21 = #(0 1 1 0 1)
与set!
行为形成对比:
(define a 1)
(define test2 (lambda b (begin (set! b 0) b)))
(test2 (quote a))
$26 = 0
a
$27 = 1
在这种情况下,根据我的理解,set!
将b
更改为0(而不是'评估" b
(应该是a
上面的eval
技巧在这里不起作用。
我的问题是:vector-set!
与set!
(或set-variable-value!)相比如何实施。 vector-set!
在它的第一个参数上达到顶峰吗?或者是其他东西?我试图看一些方案实现,但从代码中提取要点是棘手的。也许有人对某些(sicp风格)方案实施有解释或链接。
答案 0 :(得分:1)
函数vector-set!
是所谓的原语。
它是一个函数(不是特殊形式),但必须在运行时内实现。
注意:特殊表单是使用与普通应用程序中使用的顺序不同的评估顺序的表单。因此,if
,cond
,or
和其他形式是特殊形式。
某些实现(我不记得Guile是否是其中之一)有一个函数primitive?
,可用于测试函数是否是原语。
> (primitive? vector-set!)
#t
答案 1 :(得分:1)
在"一些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)))
和make-vector
由
(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
这里的向量由底层Scheme实现中的标记列表(不是定义的Scheme)表示,其变异原语(如set-car!
)用于操作它们。如果您的实现语言是C,比如说,您只需使用C数组作为向量表示,或者可能是将数组与其他相关信息(如大小等)耦合的结构。