1

このコードのビットは、Ikarus の の実装にありvector-mapます。

     (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名前付き let にパラメーター、v、およびが含まれるのはなぜnですか?

の完全な定義は次のvector-mapとおりです。

  (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))])))])))
4

1 に答える 1

3

不要なように見えるため、理由を説明するのは困難ですが、おそらく、参照される自由変数の数を減らすための最適化です。この場合、pv、およびnは のレキシカル変数にfなり、自由な変数参照を必要としなくなります。

ただし、対応する自由変数は実際にはレキシカル変数でvector-mapあり、それ以上変更されないため、コンパイラがこの種の最適化を内部的に自動的に行うことは難しくありません。さて、Ikarus にコンパイラがない場合、それが手動最適化の説明になるかもしれません。

于 2011-07-06T12:30:15.103 に答える