Subject: bug#65344: 28.2; Unable to Edebug cl-flet form which uses argument destructuring

From: Stefan Monnier <[email-masked]>
Date: Sat, 02 Sep 2023 13:04:57 -0400

>>> The problem seems to be the attempt to first match the spec
>>>
>>>   (&define [&name symbolp "@cl-flet@"]
>>>            [&name [] gensym] ;Make it unique!
>>>            def-form)])
>>
>> I think this is not right:
>>
>> - `def-form` is for use by forms which will be run "later", meaning that
>>   we can start executing those instrumented form while running
>>   non-instrumented code  (like the inside of a lambda), so it should not
>>   be needed here: we should use just `form`.
>
> I don't think I get that yet.  Let's say we have
>
>   (cl-flet ((f (lambda () (list 1 2))))
>     (f))
>
> In this case, the code for F will be run in the body of the
> flet. Doesn't that qualify as being run later, as you describe above, 
> ignoring the "non-instrumented" part, maybe?

No, in the above case the `def-form` is

    (lambda () (list 1 2))

which will be "run" right when we enter the `cl-flet` ("run" is an
exaggeration here since this lambda is a constant so it'll just
self-evaluate) and not when `f` is called.

> (Just from the perspective of behaviour, C-u C-M-x on the flet above does
> seem to do what I'd expect: the call to F let's me step into the
> body of the lambda.)

Yes, it is harmless for debugging purposes (at most it makes things ever
so slightly less efficient by having to process a few more
`edebug-enter`s than needed).

>> - The &define+&name isn't quite right here.  In `(cl-flet ((F EXP)) ...)`
>>   it tells Edebug that EXP should be given the name F whereas the `cl-flet`
>>   actually gives the name F to the value returned by EXP.
>>   [ In terms of code coverage, F will then always be considered as
>>     covered just because we have to execute EXP in order to discover the
>>     function to bind to F.  ]
>>
>> I think that's why the old code had just `(symbolp form)`:
>> it's difficult with `(cl-flet ((F EXP)) ...)` to give a name to the
>> right thing :-(
>
> I'm afraid I know nothing about coverage, so I can't say something
> halfways intelligent to that.

The whole `&name` business is of no use for the single-step debugger,
it's only useful for other uses of the instrumentation such as
code-coverage.

        Stefan