Subject: Re: byte-compile-let: reversing the order of evaluation of the clauses CAN make a difference.

From: Stefan Monnier <[email-masked]>
Date: Sun, 12 Nov 2023 12:06:27 -0500

>> Sounds like a bug.  Do you have some recipe to reproduce it?
> Certainly!  In the code fragment above in jit-lock--debug-fontify,
> insert the diagnostic line as above.  Byte compile this function.  Then
> M-x jit-lock-debug-mode.  Now scrolling any (previously unfontified)
> sections of a buffer will fail to fontify those sections.  In *Messages*
> it can be seen that the printed values of BEG and END are identical,
> hence the call to jit-lock-fontify-now does nothing.

Hmm, indeed, thanks.
Apparently Matthias already found the problem, I'm looking forward to
his explanations.

>> since computing E pushes it value on the stack, so after the two
>> "compute" we have the values of E1 and E2 on the stack and we can pop
>> them in reverse order.
>
> It seems apparent that the computations are being done in reverse order,
> too.  That can be seen in the above *Messages* output as well as in
> byte-compile-let in bytecomp.el:
>
>       (dolist (var (if is-let (reverse clauses) clauses))
>         (unless is-let
>           (push (byte-compile-push-binding-init var) init-lexenv))
>         (let ((var (if (consp var) (car var) var)))
>           (if (byte-compile-bind var init-lexenv)
>               (pop init-lexenv))))
>
> ..  (reverse clauses) happens before the code for any of the value forms
> gets generated.

AFAICT "the code for any of the value forms" is generated by
`byte-compile-push-binding-init`.  When `is-let` is true, the above loop
does not call it at all, it only emits the code which does the
`varbind` thingies.  When `is-let` is true the calls to
`byte-compile-push-binding-init` are performed just before this loop
(and non-reversed).

Maybe having written this code I'm unable to see what it actually does
instead of seeing what I want(ed) it to do, but my impression is that if
it really does it in the wrong order, we'd have noticed a long time ago.

My crystal ball doesn't want to talk to me today, but my hope is that
it's a bug in something like our new-ish variable/constant-propagation
optimization.

> This is a bug in either the byte compiler or the documentation of let.
> I would tend towards the first of these alternatives.

+1

        Stefan

PS: BTW, Alan, thanks for putting me in `Cc:`; even better would
    have been to put me in `X-Debbugs-Cc:`.