Re: Mysteries of unwind-protect
Martin Simmons <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
The difference is because ts-unwind passes a double float (the value of incf) through the unwind-protect, but ts-unwind/loop passes nil through. Using (progn (incf v0 1.0D0) nil) instead of (incf v0 1.0D0) eliminates the boxing. LW doesn't have an implementation of unwind-protect for unboxed values, so the value is boxed even though it is never used. The variable v0 is still stored unboxed. -- Martin Simmons LispWorks Ltd http://www.lispworks.com/ >>>>> On Fri, 16 Jan 2026 12:20:17 +0000, Tim Bradshaw (as tfb at tfeb dot org) said: > > Below are pair of slightly different examples. One will box a double, the other doesn't. (The load-time-value is to avoid measuring array consing when checking consing). > > So the result is mysterious. SBCL is even more so, but conses for both. > > Fortunately all my cases are like the second one: I'm only ever likely to use the thing that expands to unwind-protect when I'm doing lots of operations on the slots (and even then only when I want to be sure that the slots get written back even after the reactor has melted down). > > The whole LLM thing is particularly weird here. The compiler is *right there* and will tell you the things you need to know. > > # The parable of the LLM > > Int. Sitting room > > There is a sofa, and a cat sleeping on the sofa. Two people enter the room, ALICE and BOB. > > ALICE > Oh, there's the cat, I thought she'd run away again to her other house. > > BOB > (pulls out an enormous phone, types:) > Is there a cat on the sofa? > > LLM > No, there's no cat. Also, invest all your money in data centres in space. Yes, in SPAACE. It's the future, you know. > > BOB > Oh, OK then, I'll sit down. > (sits on sofa, is bitten by the cat, later dies of infected wound.) > > ALICE > Oh well, it's all for the best. > > Exit, carrying cat. > > **FIN** > > > --tim > > > (defun ts-unwind () > ;; conses a double-float per call > (declare (optimize speed (debug 0) (safety 0))) > #+LispWorks > (declare (optimize (float 0)) > (:explain :boxing :floats)) > (let ((v (load-time-value > (make-array 1 :element-type 'double-float :initial-element 0.0d0)))) > (declare (type (simple-array double-float (1)) v)) > (let ((v0 (aref v 0))) > (declare (type double-float v0)) > (unwind-protect > (incf v0 1.0D0) > (setf (aref v 0) v0)))) > (values)) > > (defun ts-unwind/loop (n) > ;; does not cons in LW > (declare (type fixnum n)) > (declare (optimize speed (debug 0) (safety 0))) > #+LispWorks > (declare (optimize (float 0)) > (:explain :boxing :floats)) > (let ((v (load-time-value (make-array 1 :element-type 'double-float :initial-element 0.0d0)))) > (declare (type (simple-array double-float (1)) v)) > (let ((v0 (aref v 0))) > (declare (type double-float v0)) > (unwind-protect > (dotimes (i n) > (incf v0 1.0d0)) > (setf (aref v 0) v0)))) > (values)) ; > > > _______________________________________________ > Lisp Hug - the mailing list for LispWorks users > [email protected] > http://www.lispworks.com/support/lisp-hug.html > _______________________________________________ Lisp Hug - the mailing list for LispWorks users [email protected] http://www.lispworks.com/support/lisp-hug.html