方案向量集的实现
Implementation of scheme vector-set
我想了解 vector-set!
是如何实现的。在我看来 vector-set!
是一种特殊形式 - 很像 set!
是。当我查看使用 vector-set!
的示例时,我看到了以下令人满意的行为(诡计)。
(define test (lambda (v i) (vector-set! v i 0)))
(define v (make-vector 5 1))
v
= #(1 1 1 1 1)
(test v 0)
v
= #(0 1 1 1 1)
这个我也可以(诡计)
(define test (lambda (v i) (vector-set! (eval v (interaction-environment)) i 0)))
(test (quote v) 3)
v
= #(0 1 1 0 1)
对比 set!
行为:
(define a 1)
(define test2 (lambda b (begin (set! b 0) b)))
(test2 (quote a))
= 0
a
= 1
在这种情况下,根据我的理解,set!
将 b
更改为 0(而不是“评估的”b
(应该是 a
)。 eval
上面的技巧在这里不起作用。
我的问题是:与 set!
(或 set-variable-value!)相比,vector-set!
是如何实现的。 vector-set!
是否在第一个参数处达到峰值?或者是其他东西?我试图查看一些方案实现,但从代码中提取要点很棘手。也许有人对某些(sicp 样式)方案实施有解释或 link。
函数vector-set!
是所谓的原语。
它是一个函数(不是特殊形式),但必须在运行时内实现。
注意:特殊表单是一种使用与正常应用程序中使用的顺序不同的评估顺序的表单。所以if
、cond
、or
等都是特殊形式。
一些实现(我不记得 Guile 是不是其中之一)有一个函数 primitive?
可以用来测试一个函数是否是原语。
> (primitive? vector-set!)
#t
在 "some SICP-style Scheme implementation" 中,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 数组作为向量表示,或者可能是将数组与其他相关信息(如大小等)耦合的结构。
我想了解 vector-set!
是如何实现的。在我看来 vector-set!
是一种特殊形式 - 很像 set!
是。当我查看使用 vector-set!
的示例时,我看到了以下令人满意的行为(诡计)。
(define test (lambda (v i) (vector-set! v i 0)))
(define v (make-vector 5 1))
v
= #(1 1 1 1 1)
(test v 0)
v
= #(0 1 1 1 1)
这个我也可以(诡计)
(define test (lambda (v i) (vector-set! (eval v (interaction-environment)) i 0)))
(test (quote v) 3)
v
= #(0 1 1 0 1)
对比 set!
行为:
(define a 1)
(define test2 (lambda b (begin (set! b 0) b)))
(test2 (quote a))
= 0
a
= 1
在这种情况下,根据我的理解,set!
将 b
更改为 0(而不是“评估的”b
(应该是 a
)。 eval
上面的技巧在这里不起作用。
我的问题是:与 set!
(或 set-variable-value!)相比,vector-set!
是如何实现的。 vector-set!
是否在第一个参数处达到峰值?或者是其他东西?我试图查看一些方案实现,但从代码中提取要点很棘手。也许有人对某些(sicp 样式)方案实施有解释或 link。
函数vector-set!
是所谓的原语。
它是一个函数(不是特殊形式),但必须在运行时内实现。
注意:特殊表单是一种使用与正常应用程序中使用的顺序不同的评估顺序的表单。所以if
、cond
、or
等都是特殊形式。
一些实现(我不记得 Guile 是不是其中之一)有一个函数 primitive?
可以用来测试一个函数是否是原语。
> (primitive? vector-set!)
#t
在 "some SICP-style Scheme implementation" 中,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 数组作为向量表示,或者可能是将数组与其他相关信息(如大小等)耦合的结构。