On Tue, Jan 30, 2024 at 11:13 PM Stefan Monnier <monnier@iro.umontreal.ca> wrote:

  E.g. for `eglot-server-programs` it seems that we
> will/would suffer because we start by testing `functionp` instead of
> first handling the non-function-like lists.
 
Yeah but, I could fix that if I had a time machine :-)
Anyway I tend to think it makes the code simpler to get that functionp case
out of the way first and it doesn't seem I'm alone.  Have you grepped for the 
words "can also be a function" ? It sure seems to suggest many many others
do the same: start by calling functionp.  Won't they _all_ be broken if users
have been putting lists in those user vars by mistake?

> >> We could also consider an intermediate step where `functionp` returns
> >> t but emits a warning.
> > Indeed, though in that case I'd make the funcall warn. I think it's there
> > that this proposed runtime warning  ultimately matters and is useful
> > to help users correct their elisp. Runtime warnings are a bit icky though
> > :-| but better than nothing.
>
> We already have compile time warnings at those places where the compiler
> easily knows that the list should be a function, but for all those other
> cases (like `eglot-server-programs`), we don't have any tool currently
> other than run-time warnings.

Of course.  What I'm saying is basically.  

* Do this patch, it's probably a good step.
* keep functionp returning t for those lists for a while (say one major version)
  to avoid too much fallout.  
* warn at runtime in the funcall.  Then users using these problematic 
customizations will start fixing  their code. We'll probably catch some 
library doing this too.

One thing it'd be nice to have for runtime warnings is some kind of
file location hint.  Maybe check the calling frame?

> >> - it can give a wrong impression to a beginner, encouraging confusion.
> >> - it can occasionally hide an error, making debugging a bit more difficult.
> > Wouldn't you add "complicates type propagation, static analysis and
> > optimization" to that list?
>
> No.  All these can be blissfully unaware of what `funcall` does when
> presented with a list starting with `lambda`.  In theory, it's true that
> analysis&optimization could assume that *after* the `funcall` the
> argument was a valid function obeying `functionp`, but I suspect our
> analysis/optimization technology is pretty far from that level, and even
> if we were able to make that work, the potential for gains from such
> information seems vanishingly small.

Dunno.  SBCL's compiler is pretty good, it propagates types  and warns
say, when using generic+ instead of must faster fixum+.  You can really
extract  some good perf from it.  Our byte-compiler is not advanced enough?
Maybe.  But what about the native compiler?  And shouldn't we be making
way for these advances.  

All in all, I can't see how these fishy funcalls don't amount to anything
other than 'eval' in disguise. And though I'm admittedly not as expert in
this field as you are, I've always learned  'eval' is known to be nono 
because of these and other pitfalls.  See e.g. this very good Rainer Joswig 
answer https://stackoverflow.com/a/2571549 (I'm aware you're probably
aware of those arguments, just mentioned for others who may be interested).

João