レンゾはすでに引数がリストにあり、いくつかのインタプリタが正しいと仮定しています。 eval
のほとんどの実装はこのようになり、実際のラムダ実装はの前にevlis
となります。
最も効率的なScheme実装は、コードをスタックマシンとして実行するため、すべての変数はネイティブプログラムと同様にスタックへのオフセットポインタに過ぎません。 (lambda l l)
が動作するためには、l
は、関数の最初にO((length n))
というタスクを実行し、その新たに作成されたリストのアドレスを持つ1つのスタック引数を持つように、すべての引数から引き継ぐ必要があります。次に、そのアドレスをスタックに戻して返します。
append
は、2つの引数としてリストを取得します。したがって、スタックには2つのアドレスがあるため、スタックからそれらを作成する必要はありません。 append
はl1
のコピーを作成し、l1
が空のリストの場合は、最後のペアのcdrとして何もせずにl2
を使用します。例として:ここで
(define test1 '(1 2 3))
(define test2 '(4 5 6))
(define test3 (append test1 test2))
test3 ; ==> (1 2 3 4 5 6)
(eq? (cdddr test3) test2) ; ==> #t (they are the same)
(define test4 (append test1 '()))
test4 ; ==> (1 2 3)
(equal? test1 test4) ; ==> #t
(eq? test1 test4) ; ==> #f (they just look the same)
は最初append
に必要な手順です:
(append '(1 2 3) '(4 5 6)) ; ==
(cons '1 (append '(2 3) '(4 5 6)) ; ==
(cons '1 (cons '2 (append '(3) '(4 5 6))) ; ==
(cons '1 (cons '2 (cons 3 (append '() '(4 5 6)))) ; ==
(cons '1 (cons '2 (cons 3 '(4 5 6))) ; ==
あなたはそれがO((+ 1 (length l1)))
おおセットのように私の解釈で見ることができるように!ありがとう、 – Naman
しかし、RacketとIkarusのような効率的な実装は、引数をスタックに保持しています。スタックに割り当てられた引数は、どのようにしてO(1)のペアになりますか? – Sylwester