In article <
201203061...@kylheku.com>,
To expand on what Kaz said (which is entirely correct), this:
(let ((x ...))
...
(setf x)
...
)
is formally equivalent to this:
(let ((x ...))
...
(let ((x ...))
...
))
In fact, a good compiler will emit identical code for both.
? (defun f1 (x) (let ((x (cons x x))) x))
F1
? (defun f2 (x) (setf x (cons x x)) x)
F2
? (disassemble 'f1)
;;; (defun f1 (x) (let ((x (cons x x))) x))
L0
[0] (leaq (@ (:^ L0) (% rip)) (% fn))
[7] (cmpl ($ 8) (% nargs))
[10] (jne L73)
[12] (pushq (% rbp))
[13] (movq (% rsp) (% rbp))
[16] (pushq (% arg_z))
;;; (let ((x (cons x x))) x)
[17] (movq (% arg_z) (% arg_y))
[20] (subq ($ 13) (@ #xD8 (% rcontext)))
[28] (movq (@ #xD8 (% rcontext)) (% temp0))
[35] (cmpq (@ #xE0 (% rcontext)) (% temp0))
[42] (ja L46)
[44] (uuo-alloc)
L46
[46] (andb ($ #xF0) (@ #xD8 (% rcontext)))
[54] (movq (% arg_y) (@ 5 (% temp0)))
[58] (movq (% arg_z) (@ -3 (% temp0)))
[62] (movq (% temp0) (% arg_z))
[65] (pushq (% arg_z))
[66] (leaveq)
[67] (retq)
;;; #<no source text>
L73
[73] (uuo-error-wrong-number-of-args)
NIL
? (disassemble 'f2)
;;; (defun f2 (x) (setf x (cons x x)) x)
L0
[0] (leaq (@ (:^ L0) (% rip)) (% fn))
[7] (cmpl ($ 8) (% nargs))
[10] (jne L77)
[12] (pushq (% rbp))
[13] (movq (% rsp) (% rbp))
[16] (pushq (% save0))
[18] (movq (% arg_z) (% save0))
;;; (setf x (cons x x))
[21] (subq ($ 13) (@ #xD8 (% rcontext)))
[29] (movq (@ #xD8 (% rcontext)) (% temp0))
[36] (cmpq (@ #xE0 (% rcontext)) (% temp0))
[43] (ja L47)
[45] (uuo-alloc)
L47
[47] (andb ($ #xF0) (@ #xD8 (% rcontext)))
[55] (movq (% save0) (@ 5 (% temp0)))
[59] (movq (% save0) (@ -3 (% temp0)))
[63] (movq (% temp0) (% save0))
;;; #<no source text>
[66] (movq (% save0) (% arg_z))
[69] (popq (% save0))
[71] (leaveq)
[72] (retq)
L77
[77] (uuo-error-wrong-number-of-args)
NIL
?