Scheme 矢量地图的ikarus实现
这段代码是Ikarus实现的Scheme 矢量地图的ikarus实现,scheme,r6rs,Scheme,R6rs,这段代码是Ikarus实现的矢量地图: (let f ([p p] [v v] [i 0] [n (vector-length v)] [ac '()]) (cond [($fx= i n) (ls->vec ac n)] [else (f p v ($fxadd1 i) n (cons (p (vector-ref v i)) ac))]))] 为什么命名let包含参数p、v和n 以下是矢量地图的完整定义
矢量地图
:
(let f ([p p] [v v] [i 0] [n (vector-length v)] [ac '()])
(cond
[($fx= i n) (ls->vec ac n)]
[else
(f p v ($fxadd1 i) n (cons (p (vector-ref v i)) ac))]))]
为什么命名let包含参数p
、v
和n
以下是矢量地图的完整定义
(module (vector-map)
(define who 'vector-map)
(define (ls->vec ls n)
(let f ([v (make-vector n)]
[n n]
[ls ls])
(cond
[(null? ls) v]
[else
(let ([n ($fxsub1 n)])
($vector-set! v n ($car ls))
(f v n ($cdr ls)))])))
(define vector-map
(case-lambda
[(p v)
(unless (procedure? p)
(die who "not a procedure" p))
(unless (vector? v)
(die who "not a vector" v))
(let f ([p p] [v v] [i 0] [n (vector-length v)] [ac '()])
(cond
[($fx= i n) (ls->vec ac n)]
[else
(f p v ($fxadd1 i) n (cons (p (vector-ref v i)) ac))]))]
[(p v0 v1)
(unless (procedure? p)
(die who "not a procedure" p))
(unless (vector? v0)
(die who "not a vector" v0))
(unless (vector? v1)
(die who "not a vector" v1))
(let ([n (vector-length v0)])
(unless ($fx= n ($vector-length v1))
(die who "length mismatch" v0 v1))
(let f ([p p] [v0 v0] [v1 v1] [i 0] [n n] [ac '()])
(cond
[($fx= i n) (ls->vec ac n)]
[else
(f p v0 v1 ($fxadd1 i) n
(cons (p ($vector-ref v0 i) ($vector-ref v1 i)) ac))])))]
[(p v0 v1 . v*)
(unless (procedure? p)
(die who "not a procedure" p))
(unless (vector? v0)
(die who "not a vector" v0))
(unless (vector? v1)
(die who "not a vector" v1))
(let ([n (vector-length v0)])
(unless ($fx= n ($vector-length v1))
(die who "length mismatch" v0 v1))
(let f ([v* v*] [n n])
(unless (null? v*)
(let ([a ($car v*)])
(unless (vector? a)
(die who "not a vector" a))
(unless ($fx= ($vector-length a) n)
(die who "length mismatch")))
(f ($cdr v*) n)))
(let f ([p p] [v0 v0] [v1 v1] [v* v*] [i 0] [n n] [ac '()])
(cond
[($fx= i n) (ls->vec ac n)]
[else
(f p v0 v1 v* ($fxadd1 i) n
(cons
(apply p ($vector-ref v0 i) ($vector-ref v1 i)
(let f ([i i] [v* v*])
(if (null? v*)
'()
(cons ($vector-ref ($car v*) i)
(f i ($cdr v*))))))
ac))])))])))
很难说为什么,因为这似乎是不必要的,但这可能是一种优化,以减少引用的自由变量的数量。在这种情况下,p
、v
和n
成为f
的词汇变量,不再需要自由变量引用
然而,由于相应的自由变量实际上是向量映射的词法变量,并且没有进一步修改,因此编译器在内部自动进行这种优化应该不难。现在,如果Ikarus没有编译器,那么这可能解释了手动优化。Ikarus是一个(优化)编译器,所以看起来不太可能。