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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.