help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Easy to add with push but not to the end of a list


From: Stefan Monnier
Subject: Re: Easy to add with push but not to the end of a list
Date: Tue, 06 Dec 2022 08:56:09 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

>> That supports generalized variables; you don't need to do
>> that (unless you want to).
>
> Just wonder why mine looks so different ...

Because when you want to do:

    (push V (aref A (cl-incf I)))

the naive expansion gives:

    (setf (aref A (cl-incf I))
          (cons V (aref A (cl-incf I))))

which will increment I twice :-(
So the expansion need to look like:

    (let ((tmp (cl-incf I)))
      (setf (aref A tmp)
            (cons V (aref A tmp))))

And of course, the same holds if A is not just a variable reference but
say a call to function that's costly or that is not pure.
Furthermore, the above performs the `cl-incf` before computing V, so if
V is an expression that uses I it changes the expected result compared
to the usual left-to-right evaluation order provided by ELisp.
So in the end you need something like:

    (let ((tmp1 V)
          (tmp2 A)
          (tmp3 (cl-incf I)))
      (setf (aref tmp2 tmp3)
            (cons tmp1 (aref tmp2 tmp3))))


-- Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]