bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Pip Cet
Recipe starting from emacs -Q:

M-: (funcall #'or) RET

Expected result:

An error, as `or' is not a function.

Actual result:

nil
------
Effectively, this makes `funcall' behave as though it were a macro,
even though it is a function.

Probably not a serious issue, but it can confuse people into thinking
that "funcall" accepts macros in general, which it doesn't do. It
certainly confused me (the byte compiler also mis-compiles (apply #'or
nil), which did not help).



Reply | Threaded
Open this post in threaded view
|

bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Lars Ingebrigtsen
Pip Cet <[hidden email]> writes:

> Recipe starting from emacs -Q:
>
> M-: (funcall #'or) RET
>
> Expected result:
>
> An error, as `or' is not a function.

M-: (funcall 'or)
-> funcall: Invalid function: #<subr or>

So, indeed, that does seem rather inconsistent.

--
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



Reply | Threaded
Open this post in threaded view
|

bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Philipp Stephani
In reply to this post by Pip Cet
Am Fr., 19. Feb. 2021 um 15:03 Uhr schrieb Andreas Schwab
<[hidden email]>:
>
> On Feb 19 2021, Pip Cet wrote:
>
> > Recipe starting from emacs -Q:
> >
> > M-: (funcall #'or) RET
>
> If you want authentic results, use ielm, not eval-expression.
>


Ah, so the rewrite that macroexpand-all (in macroexp--expand-all)
performs is the culprit here. Maybe it should only rewrite if the
first argument is indeed a function, or an autoload of a function?



Reply | Threaded
Open this post in threaded view
|

bug#46636: [External] : bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Drew Adams
In reply to this post by Pip Cet
> M-: (funcall #'or) RET
> Expected result:
> An error, as `or' is not a function.
> Actual result:
> nil
> ------
> Effectively, this makes `funcall' behave as though it were a macro,
> even though it is a function.
>
> Probably not a serious issue, but it can confuse people into thinking
> that "funcall" accepts macros in general, which it doesn't do. It
> certainly confused me (the byte compiler also mis-compiles (apply #'or
> nil), which did not help).

Yeah, this is bad, IMO.  Confuses users and leads
them down the garden path.  Common Lisp and other
Lisps haven't done this, AFAIK.
Reply | Threaded
Open this post in threaded view
|

bug#46636: [External] : bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Richard Stallman
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I think I agree that funcalling `or' should give an error.

--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





Reply | Threaded
Open this post in threaded view
|

bug#46636: [External] : bug#46636: 28.0.50; M-: (funcall #'or) doesn't throw an error

Pip Cet
On Mon, Feb 22, 2021 at 6:20 AM Richard Stallman <[hidden email]> wrote:
> I think I agree that funcalling `or' should give an error.

This applies to all macros. I chose #'or as an example because it is
often used as though it were a function, so people might be confused
into trying it (as I have, I must confess).

(funcall #'setq x 3)

also "works", and it's clear in that case that it should not.

I think the right way to fix this is not to macroexpand (funcall #'f)
in eval-expression, but to leave it to the byte compiler to do so; the
byte compiler often assumes that function bindings don't change, so it
would not be a new problem for it to also assume that if #'or is a
macro at compile time, it will be a macro at runtime, so it can avoid
simplifying calls to well-known macros, at least.