GNU bug report logs - #40968
28.0.50; (apply nil)

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> gmail.com>

Date: Wed, 29 Apr 2020 18:27:02 UTC

Severity: normal

Tags: fixed

Found in version 28.0.50

Fixed in version 28.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 40968 in the body.
You can then email your comments to 40968 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 29 Apr 2020 18:27:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Pip Cet <pipcet <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 29 Apr 2020 18:27:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.0.50; (apply nil)
Date: Wed, 29 Apr 2020 18:26:15 +0000
I'm very confused by the behavior of `apply' when given only a single
argument: when it's a nonempty list, the argument gets spread out and
passed to Ffuncall (I guess this might be useful sometimes). When it's
nil, Ffuncall gets called with nargs == 0 and Emacs crashes, at least
sometimes.

Should we fix the special case or raise apply's minimum argument count to 2?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 29 Apr 2020 18:37:02 GMT) Full text and rfc822 format available.

Message #8 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 29 Apr 2020 18:35:42 +0000
On Wed, Apr 29, 2020 at 6:27 PM Pip Cet <pipcet <at> gmail.com> wrote:
> Should we fix the special case or raise apply's minimum argument count to 2?

The byte compiler also gets single-argument `apply' "wrong", so the
latter would seem to be the best option, to me.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 01:52:01 GMT) Full text and rfc822 format available.

Message #11 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Tue, 5 May 2020 21:51:11 -0400
Pip Cet <pipcet <at> gmail.com> writes:

> I'm very confused by the behavior of `apply' when given only a single
> argument: when it's a nonempty list, the argument gets spread out and
> passed to Ffuncall (I guess this might be useful sometimes). When it's
> nil, Ffuncall gets called with nargs == 0 and Emacs crashes, at least
> sometimes.
>
> Should we fix the special case or raise apply's minimum argument count to 2?

I'm personally not a big fan of raising the minimum argument count,
thereby changing the function signature and making it harder to
understand.

We should just fix the bug, IMHO.

Best regards,
Stefan Kangas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 07:28:01 GMT) Full text and rfc822 format available.

Message #14 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 07:26:36 +0000
On Wed, May 6, 2020 at 1:51 AM Stefan Kangas <stefan <at> marxist.se> wrote:
> Pip Cet <pipcet <at> gmail.com> writes:
> > I'm very confused by the behavior of `apply' when given only a single
> > argument: when it's a nonempty list, the argument gets spread out and
> > passed to Ffuncall (I guess this might be useful sometimes). When it's
> > nil, Ffuncall gets called with nargs == 0 and Emacs crashes, at least
> > sometimes.
> >
> > Should we fix the special case or raise apply's minimum argument count to 2?
>
> I'm personally not a big fan of raising the minimum argument count,
> thereby changing the function signature and making it harder to
> understand.

Thanks. I disagree that it would be harder to understand, though: "the
first argument is a function to call, the last argument is a list of
arguments" is easy to understand when there are >= 2 arguments, but
for a single argument they're in contradiction, aren't they? Indeed,
I'd read Fapply's current docstring:

Call FUNCTION with our remaining args, using our last arg as list of args.

as implying that (apply FUNCTION) is equivalent to (funcall FUNCTION)

> We should just fix the bug, IMHO.

I don't think we can "just" fix the bug. We need to fix Fapply, change
the byte compiler to accept single-argument apply, reformulate the
docstring to describe this case, and probably fix the Lisp manual as
well. I don't think all that is worth it, to be honest, to save
someone the trouble of having to write (apply (car LIST) (cdr LIST))
rather than (apply LIST) (if that is, indeed, what they meant).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 10:19:02 GMT) Full text and rfc822 format available.

Message #17 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil) 
Date: Wed, 6 May 2020 12:18:44 +0200
> The byte compiler also gets single-argument `apply' "wrong", so the latter would seem to be the best option, to me. 

Strong agreement! An 'apply' that actually does 'eval'...
Will you write the patch or shall I?





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 10:47:02 GMT) Full text and rfc822 format available.

Message #20 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: bug-gnu-emacs <at> gnu.org,
 Mattias Engdegård <mattiase <at> acm.org>,
 Pip Cet <pipcet <at> gmail.com>, "Richard M. Stallman" <rms <at> gnu.org>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 06 May 2020 13:45:51 +0300
On May 6, 2020 1:18:44 PM GMT+03:00, "Mattias Engdegård" <mattiase <at> acm.org> wrote:
> > The byte compiler also gets single-argument `apply' "wrong", so the
> latter would seem to be the best option, to me. 
> 
> Strong agreement! An 'apply' that actually does 'eval'...
> Will you write the patch or shall I?

Hmm... but Fapply clearly attempts to handle the case of zero arguments.  Richard  do you remember what use cases was that supposed to handle?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 10:47:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 10:59:01 GMT) Full text and rfc822 format available.

Message #26 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Andreas Schwab <schwab <at> linux-m68k.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mattiase <at> acm.org, stefan <at> marxist.se, 40968 <at> debbugs.gnu.org, rms <at> gnu.org,
 pipcet <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 06 May 2020 12:57:58 +0200
On Mai 06 2020, Eli Zaretskii wrote:

> Hmm... but Fapply clearly attempts to handle the case of zero
> arguments.

I don't think it does.  It handles (apply ... nil) (numargs is the
length of the last argument), but mishandles the boundary case (when
nargs is one).

Andreas.

-- 
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 11:25:02 GMT) Full text and rfc822 format available.

Message #29 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 07:24:13 -0400
Pip Cet <pipcet <at> gmail.com> writes:

> Thanks. I disagree that it would be harder to understand, though: "the
> first argument is a function to call, the last argument is a list of
> arguments" is easy to understand when there are >= 2 arguments, but
> for a single argument they're in contradiction, aren't they? Indeed,
> I'd read Fapply's current docstring:

I have a feeling I'm missing something obvious here.  The current
function signature is:

   (apply FUNCTION &rest ARGUMENTS)

How would your proposal change that?

Best regards,
Stefan Kangas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 11:27:01 GMT) Full text and rfc822 format available.

Message #32 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 11:25:19 +0000
[Message part 1 (text/plain, inline)]
On Wed, May 6, 2020 at 10:18 AM Mattias Engdegård <mattiase <at> acm.org> wrote:
> > The byte compiler also gets single-argument `apply' "wrong", so the latter would seem to be the best option, to me.
>
> Strong agreement! An 'apply' that actually does 'eval'...

Well, it's not quite `eval': the arguments aren't evaluated again.

The obvious single-character patch results in four warnings when
rebuilding Emacs, all of which seem to use the previous semantics, so
I think it might be best to document this behavior and simply catch
(apply nil).
[0001-Require-at-least-two-arguments-for-Fapply.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 11:50:02 GMT) Full text and rfc822 format available.

Message #35 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 13:49:13 +0200
6 maj 2020 kl. 13.25 skrev Pip Cet <pipcet <at> gmail.com>:

> The obvious single-character patch results in four warnings when
> rebuilding Emacs, all of which seem to use the previous semantics, so
> I think it might be best to document this behavior and simply catch
> (apply nil).

There is one in cl-generic-tests.el, too.
It appears in one GNU ELPA package as well, and in one other external package where it seems to be a misunderstanding of apply:

(cl-defun nim-log (&rest msg-and-rest)
  (apply `((lambda () (lwarn 'nim :debug ,@msg-and-rest)))))






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 11:51:02 GMT) Full text and rfc822 format available.

Message #38 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 11:49:26 +0000
On Wed, May 6, 2020 at 11:24 AM Stefan Kangas <stefan <at> marxist.se> wrote:
> Pip Cet <pipcet <at> gmail.com> writes:
> I have a feeling I'm missing something obvious here.  The current
> function signature is:
>
>    (apply FUNCTION &rest ARGUMENTS)
>
> How would your proposal change that?

(apply FUNCTION ARGUMENT &rest ARGUMENTS), I guess. I missed it in the
first patch.

Note that the old signature suggests (apply FUNCTION) is equivalent to
(funcall FUNCTION), which it isn't. (For example, that's what ElDoc
indicates the first argument to apply is).

Again, I'm no longer sure what the right thing to do here is.  I think
I'm up to five different interpretations of (apply ARG) here,
depending on whether ARG is interpreted as FUNCTION, the last of the
ARGUMENTS, an ARGUMENT but not the last one, or a combination thereof,
and whether ARG is required to be a list or not...




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 13:03:02 GMT) Full text and rfc822 format available.

Message #41 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 06:02:45 -0700
Pip Cet <pipcet <at> gmail.com> writes:

> (apply FUNCTION ARGUMENT &rest ARGUMENTS), I guess. I missed it in the
> first patch.

Thanks.

FWIW, I still think we should avoid changing the function signature if
at all possible.

apply is fundamental to Lisp, and has been defined like this for a
long time.  See the definition of "The Universal S-Function apply" in
John McCarthy's paper: [1]

    apply[f;args] =eval[cons[f;appq[args]];NIL],

Also note that it is still defined like this elsewhere:

Scheme: (apply function argument-list)
Common Lisp:  apply function &rest args+ => result*
Clojure: (apply f args)

Best regards,
Stefan Kangas

Footnotes:
[1]  http://www-formal.stanford.edu/jmc/recursive.pdf




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 13:57:01 GMT) Full text and rfc822 format available.

Message #44 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 13:55:55 +0000
On Wed, May 6, 2020 at 1:02 PM Stefan Kangas <stefan <at> marxist.se> wrote:
> Pip Cet <pipcet <at> gmail.com> writes:
> > (apply FUNCTION ARGUMENT &rest ARGUMENTS), I guess. I missed it in the
> > first patch.
>
> Thanks.
>
> FWIW, I still think we should avoid changing the function signature if
> at all possible.

Is the function signature relevant for anything but eldoc?

> apply is fundamental to Lisp, and has been defined like this for a
> long time.

I don't know about that. Anything but the two-argument form of apply
strikes me as rather dialect-dependent, but I may be wrong.

> See the definition of "The Universal S-Function apply" in
> John McCarthy's paper: [1]
>
>     apply[f;args] =eval[cons[f;appq[args]];NIL],

I must admit I don't know how appq is defined.

> Also note that it is still defined like this elsewhere:

I may be misreading your examples, but they seem to me to have
different signatures from the one hitherto used in Emacs.

> Scheme: (apply function argument-list)

Precisely two args, right?

> Common Lisp:  apply function &rest args+ => result*

At least two args.

> Clojure: (apply f args)

Precisely two args again?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 14:05:02 GMT) Full text and rfc822 format available.

Message #47 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org, pipcet <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 06 May 2020 17:03:59 +0300
> From: Stefan Kangas <stefan <at> marxist.se>
> Date: Wed, 6 May 2020 06:02:45 -0700
> Cc: 40968 <at> debbugs.gnu.org
> 
> Pip Cet <pipcet <at> gmail.com> writes:
> 
> > (apply FUNCTION ARGUMENT &rest ARGUMENTS), I guess. I missed it in the
> > first patch.
> 
> Thanks.
> 
> FWIW, I still think we should avoid changing the function signature if
> at all possible.

I agree.  I also think it isn't enough to check only here and in ELPA:
'apply' is a very popular function, and is used very widely.  I won't
be surprised if there were more of these usage cases that would be
broken by such a change in the signature.

Can we instead identify the problematic usage and signal an error?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 15:29:01 GMT) Full text and rfc822 format available.

Message #50 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 11:28:49 -0400
Pip Cet <pipcet <at> gmail.com> writes:

> Is the function signature relevant for anything but eldoc?

Besides the docstring, the manual documents it.  The suggested form is
unusual and makes it harder to understand, IMHO.

>> apply is fundamental to Lisp, and has been defined like this for a
>> long time.
>
> I don't know about that. Anything but the two-argument form of apply
> strikes me as rather dialect-dependent, but I may be wrong.

If I understand correctly, you propose a three argument form:

    (apply FUNCTION ARGUMENT &rest ARGUMENTS)

This is what I find unusual.  It should really be either

    (apply FUNCTION &rest ARGUMENTS)

or

    (apply FUNCTION ARGUMENTS)

But since we already have the former, we are better to stick with
that.

Maybe there's a case to be made for a syntactic alternative to "&rest"
which disallows nil, which I guess is the issue here?  But we can also
just signal an error in this case.

Racket does the latter, as one data point:

    > (define foo (lambda () 1))
    > (apply foo nil)
    ; nil: undefined;
    ;  cannot reference an identifier before its definition
    ;   in module: top-level
    ; [,bt for context]

BTW, I don't see a big difference conceptually between '&rest
ARGUMENTS' and 'ARGUMENTS'.  The former is just syntactic sugar,
right?

>> See the definition of "The Universal S-Function apply" in
>> John McCarthy's paper: [1]
>>
>>     apply[f;args] =eval[cons[f;appq[args]];NIL],
>
> I must admit I don't know how appq is defined.

My point is mainly that it has two arguments: f and args.

Best regards,
Stefan Kangas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 17:47:01 GMT) Full text and rfc822 format available.

Message #53 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Pip Cet <pipcet <at> gmail.com>, Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 10:46:04 -0700 (PDT)
Dunno whether this has been mentioned in this
thread (haven't followed it).

The signature in Common Lisp (which is more or
less the _common_ ground of several Lisps from
the 70s & 80s) is this:

 (apply function arg &rest more-args)

I don't see why Emacs Lisp should be different.
Is there a good reason?  Is there some advantage
to being able to do just (apply #'foo)?  Why do
we use this signature:

 (apply FUNCTION &rest ARGUMENTS)

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node81.html




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 17:56:01 GMT) Full text and rfc822 format available.

Message #56 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 17:54:23 +0000
[Message part 1 (text/plain, inline)]
On Wed, May 6, 2020 at 2:04 PM Eli Zaretskii <eliz <at> gnu.org> wrote:
> 'apply' is a very popular function, and is used very widely.  I won't
> be surprised if there were more of these usage cases that would be
> broken by such a change in the signature.

> Can we instead identify the problematic usage and signal an error?

Yes. What we also have to do is fix the documentation, and fix the
byte optimizer.

Here's a first suggestion. I'd particularly appreciate hints on better
wording for the documentation.
[0001-Handle-single-argument-apply-consistently-bug-40968.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 18:03:01 GMT) Full text and rfc822 format available.

Message #59 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Stefan Kangas <stefan <at> marxist.se>, Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 11:00:30 -0700 (PDT)
> > (apply FUNCTION ARGUMENT &rest ARGUMENTS), I guess. I missed it in
> > the first patch.
> 
> FWIW, I still think we should avoid changing the function signature if
> at all possible.
> 
> apply is fundamental to Lisp, and has been defined like this for a
> long time.  See the definition of "The Universal S-Function apply" in
> John McCarthy's paper: [1]
> 
>     apply[f;args] =eval[cons[f;appq[args]];NIL],
> 
> Also note that it is still defined like this elsewhere:
> 
> Scheme: (apply function argument-list)
> Common Lisp: apply function &rest args+ => result*
> Clojure: (apply f args)

Hm.  CLTL2 shows the signature for Common Lisp as this:

 apply function arg &rest more-args
                ^^^

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node81.html

On the other hand the CL HyperSpec agrees with you:

 apply function &rest args+ => result*

http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm

Dunno what the truth is.  I've always considered
CLTL the language spec.  But that may be wrong.

What's the use case for (apply FUN)?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 18:08:01 GMT) Full text and rfc822 format available.

Message #62 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 18:06:31 +0000
On Wed, May 6, 2020 at 3:28 PM Stefan Kangas <stefan <at> marxist.se> wrote:
> Pip Cet <pipcet <at> gmail.com> writes:
> > Is the function signature relevant for anything but eldoc?
>
> Besides the docstring, the manual documents it.  The suggested form is
> unusual and makes it harder to understand, IMHO.

I think it's hard to understand Elisp apply from a standard signature,
because it's really

(apply FUNCTION &rest INDIVIDUAL-ARGUMENTS ARGUMENT-LIST)

or

(apply FUNCTION-AND-ARGUMENT-LIST)

The latter (which takes a single argument) is not a special case of
the former (which takes 2,3,4,... arguments).

> >> apply is fundamental to Lisp, and has been defined like this for a
> >> long time.
> >
> > I don't know about that. Anything but the two-argument form of apply
> > strikes me as rather dialect-dependent, but I may be wrong.
>
> If I understand correctly, you propose a three argument form:
>
>     (apply FUNCTION ARGUMENT &rest ARGUMENTS)

That's a 2,3,4...-argument form.

> This is what I find unusual.  It should really be either
>
>     (apply FUNCTION &rest ARGUMENTS)

That's a 1,2,3...-argument form.

> or
>
>     (apply FUNCTION ARGUMENTS)

That's a 2-argument form.

> But since we already have the former, we are better to stick with
> that.
>
> Maybe there's a case to be made for a syntactic alternative to "&rest"
> which disallows nil, which I guess is the issue here?  But we can also
> just signal an error in this case.
>
> Racket does the latter, as one data point:
>
>     > (define foo (lambda () 1))
>     > (apply foo nil)
>     ; nil: undefined;
>     ;  cannot reference an identifier before its definition
>     ;   in module: top-level
>     ; [,bt for context]

Doesn't that just say that "nil" isn't a valid Racket identifier?
(apply foo '()) works fine, and Racket's apply requires at least two
arguments if I'm reading the error message correctly.

> BTW, I don't see a big difference conceptually between '&rest
> ARGUMENTS' and 'ARGUMENTS'.  The former is just syntactic sugar,
> right?

Not really, no.

> >> See the definition of "The Universal S-Function apply" in
> >> John McCarthy's paper: [1]
> >>
> >>     apply[f;args] =eval[cons[f;appq[args]];NIL],
> >
> > I must admit I don't know how appq is defined.

(It turns out my PDF viewer just refused to highlight the definition
right there on the page).

> My point is mainly that it has two arguments: f and args.

I think we're all in agreement about 2-argument apply.
3,4,...-argument apply is an unfortunate legacy but one we're stuck
with now. 1-argument apply is the issue here.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 18:10:02 GMT) Full text and rfc822 format available.

Message #65 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, stefan <at> marxist.se
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 06 May 2020 21:09:08 +0300
> From: Pip Cet <pipcet <at> gmail.com>
> Date: Wed, 6 May 2020 17:54:23 +0000
> Cc: Stefan Kangas <stefan <at> marxist.se>, 40968 <at> debbugs.gnu.org
> 
> > Can we instead identify the problematic usage and signal an error?
> 
> Yes. What we also have to do is fix the documentation, and fix the
> byte optimizer.
> 
> Here's a first suggestion. I'd particularly appreciate hints on better
> wording for the documentation.

The documentation parts of the patch look fine to me, thanks.  (The
rest also looks fine.)  Let's wait for a few days so others could
comment.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 18:29:01 GMT) Full text and rfc822 format available.

Message #68 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>,
 Pip Cet <pipcet <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 06 May 2020 14:28:43 -0400
Drew Adams <drew.adams <at> oracle.com> writes:

>  apply function arg &rest more-args
>                 ^^^
>
> https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node81.html
>
> On the other hand the CL HyperSpec agrees with you:
>
>  apply function &rest args+ => result*
>
> http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm

I think '&rest args+' is just BNF shorthand for 'arg &rest more-args'
(i.e., both signatures above require a total of 2 or more arguments).

http://www.lispworks.com/documentation/HyperSpec/Body/01_dab.htm




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 18:43:01 GMT) Full text and rfc822 format available.

Message #71 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: Stefan Kangas <stefan <at> marxist.se>, Eli Zaretskii <eliz <at> gnu.org>,
 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil) 
Date: Wed, 6 May 2020 20:42:34 +0200
[Message part 1 (text/plain, inline)]
That patch is fine but perhaps incomplete, if we want (apply nil) to result in the same error when interpreted and byte-compiled.
Suggested test case attached.

The manual change is fine. Perhaps we should adopt a somewhat discouraging tone.
You could also say that (apply X) is defined as (apply (car X) (cdr X)), and X must be a cons.


[test.diff (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 19:18:02 GMT) Full text and rfc822 format available.

Message #74 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>,
 Pip Cet <pipcet <at> gmail.com>
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 12:17:21 -0700 (PDT)
> >  apply function arg &rest more-args
> >                 ^^^
> >
> https://urldefense.com/v3/__https://www.cs.cmu.edu/Groups/AI/html/cltl/
> clm/node81.html__;!!GqivPVa7Brio!Kes9zsDqvdTyifr0LvhIg-
> x3qHNl3XPQZaBRBxbjXsP-qGz7ieoaYPp6rfGGzbvg$
> >
> > On the other hand the CL HyperSpec agrees with you:
> >
> >  apply function &rest args+ => result*
> >
> https://urldefense.com/v3/__http://www.lispworks.com/documentation/Hype
> rSpec/Body/f_apply.htm__;!!GqivPVa7Brio!Kes9zsDqvdTyifr0LvhIg-
> x3qHNl3XPQZaBRBxbjXsP-qGz7ieoaYPp6rY83YOj5$
> 
> I think '&rest args+' is just BNF shorthand for 'arg &rest more-args'
> (i.e., both signatures above require a total of 2 or more arguments).
> 
> https://urldefense.com/v3/__http://www.lispworks.com/documentation/Hype
> rSpec/Body/01_dab.htm__;!!GqivPVa7Brio!Kes9zsDqvdTyifr0LvhIg-
> x3qHNl3XPQZaBRBxbjXsP-qGz7ieoaYPp6rbGmUXoP$

Ah yes; thanks.

So Common Lisp is unequivocally in the camp of
requiring at least two args.

And if Elisp follows that (which I think it should,
unless someone can present a good use case for just
(apply FUNCTION)), then it should raise an error if
there are not at least two args.

Just one opinion.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 19:23:02 GMT) Full text and rfc822 format available.

Message #77 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>,
 Noam Postavsky <npostavs <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 19:21:54 +0000
On Wed, May 6, 2020 at 7:17 PM Drew Adams <drew.adams <at> oracle.com> wrote:
> And if Elisp follows that (which I think it should,
> unless someone can present a good use case for just
> (apply FUNCTION)), then it should raise an error if
> there are not at least two args.

Note that single-argument apply in current Elisp is not (apply
FUNCTION) but (apply LIST-OF-FUNCTION-PLUS-ARGS).

(apply '+) is an error.
(apply '(+)) is 0.

That's why the problem with (apply nil) arose.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 19:27:01 GMT) Full text and rfc822 format available.

Message #80 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Pip Cet <pipcet <at> gmail.com>, Stefan Kangas <stefan <at> marxist.se>
Cc: 40968 <at> debbugs.gnu.org
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 12:26:09 -0700 (PDT)
> > > Is the function signature relevant for anything but eldoc?

It should be relevant in terms of raising an error
if the signature is not respected.

> > Besides the docstring, the manual documents it.  The suggested form
> > is unusual and makes it harder to understand, IMHO.
> 
> I think it's hard to understand Elisp apply from a standard signature,
> because it's really
> 
> (apply FUNCTION &rest INDIVIDUAL-ARGUMENTS ARGUMENT-LIST)
> or
> (apply FUNCTION-AND-ARGUMENT-LIST)
> 
> The latter (which takes a single argument) is not a special case of
> the former (which takes 2,3,4,... arguments).

(apply FUNCTION) and (apply) should raise an
error, IMO (as in Common Lisp).

Is there a good use case for either?

> > If I understand correctly, you propose a three argument form:
> >     (apply FUNCTION ARGUMENT &rest ARGUMENTS)
> 
> That's a 2,3,4...-argument form.

It's what Common Lisp prescribes.

> > This is what I find unusual.  It should really be either
> >    (apply FUNCTION &rest ARGUMENTS)
> > or (apply FUNCTION ARGUMENTS)
> 
> That's a 2-argument form.

That second form is the same as (apply FUNCTION ARGUMENT).
And in that second form it's fine for ARGUMENT to be nil.

The first form should raise an error if ARGUMENTS is nil.

> > Maybe there's a case to be made for a syntactic alternative to
> > "&rest" which disallows nil, which I guess is the issue here?

An &rest which must not be nil is written as:

 ARGUMENT &rest MORE-ARGS

&rest is just a list.  It can always be nil.

> > My point is mainly that it has two arguments: f and args.
> 
> I think we're all in agreement about 2-argument apply.
> 3,4,...-argument apply is an unfortunate legacy but one we're stuck
> with now. 1-argument apply is the issue here.

I'm not in agreement, FWIW.  The behavior and its
description should be as for Common Lisp: require
at least 2 args: FUNCTION and its first ARGUMENT.

Is there some use case for (apply f) and (apply)?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 19:29:01 GMT) Full text and rfc822 format available.

Message #83 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>,
 Noam Postavsky <npostavs <at> gmail.com>
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 12:28:21 -0700 (PDT)
> > And if Elisp follows that (which I think it should,
> > unless someone can present a good use case for just
> > (apply FUNCTION)), then it should raise an error if
> > there are not at least two args.
> 
> Note that single-argument apply in current Elisp is not (apply
> FUNCTION) but (apply LIST-OF-FUNCTION-PLUS-ARGS).
> 
> (apply '+) is an error.
> (apply '(+)) is 0.
> 
> That's why the problem with (apply nil) arose.

I think (apply '(+)) should raise an error, because
(a) the first arg is not a function and (b) it's
missing a second arg.

I think (apply ()) should raise an error for the
same reason: nil is not a function, and there's no
second arg.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 20:33:01 GMT) Full text and rfc822 format available.

Message #86 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Phil Sainty <psainty <at> orcon.net.nz>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 07 May 2020 08:32:16 +1200
On 2020-05-06 23:49, Pip Cet wrote:
> Again, I'm no longer sure what the right thing to do here is.  I think
> I'm up to five different interpretations of (apply ARG) here,
> depending on whether ARG is interpreted as FUNCTION, the last of the
> ARGUMENTS, an ARGUMENT but not the last one, or a combination thereof,
> and whether ARG is required to be a list or not...

To my mind the nicest change would be to handle the two error cases,
and keep everything else the same.

1. (apply nil) would signal an error.

2. (apply FUNC) would be equivalent to funcall, rather than signalling
   an error, when (functionp FUNC) -- or perhaps just (not (consp 
FUNC)).

3. (apply LIST) would remain equivalent to (apply (car LIST) (cdr LIST))


I don't feel strongly about #2.  It seems like a nice enhancement to me,
but if others feel that would be cause problems then I wouldn't argue.
Existing uses of that in the wild are obviously signalling errors at
present, so offhand it doesn't seem to me like a dangerous change, and
it would match the existing signature.

#3 just seems like the only useful thing that apply could possibly do
with a single list argument, so I'd definitely keep that.

#2 and #3 are surely both convenient for generated code which doesn't
know how many arguments it's going to be dealing with.


I would still use (FUNCTION &optional ARGS) as the signature, and just
document what happens when FUNCTION is actually a list.


-Phil





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Wed, 06 May 2020 21:38:02 GMT) Full text and rfc822 format available.

Message #89 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Phil Sainty <psainty <at> orcon.net.nz>, Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 14:35:41 -0700 (PDT)
> To my mind the nicest change would be to handle the two error cases,
> and keep everything else the same.
> 
> 1. (apply nil) would signal an error.
> 2. (apply FUNC) would be equivalent to funcall, rather than signalling
>     an error, when (functionp FUNC) -- or perhaps just (not (consp
>     FUNC)).
> 3. (apply LIST) would remain equivalent to (apply (car LIST) (cdr
>     LIST))
> 
> I don't feel strongly about #2.  It seems like a nice enhancement to
> me,
> but if others feel that would be cause problems then I wouldn't argue.
> Existing uses of that in the wild are obviously signalling errors at
> present, so offhand it doesn't seem to me like a dangerous change, and
> it would match the existing signature.
> 
> #3 just seems like the only useful thing that apply could possibly do
> with a single list argument, so I'd definitely keep that.
> 
> #2 and #3 are surely both convenient for generated code which doesn't
> know how many arguments it's going to be dealing with.
> 
> I would still use (FUNCTION &optional ARGS) as the signature, and just
> document what happens when FUNCTION is actually a list.

What's wrong with doing what Common Lisp does
(apparently, per the doc'd signature)?

(apply FUNCTION first-arg &rest other-args)

The first arg to `apply' is required, and
must be a function.

The second arg to `apply' is required.
Any arg after the second is optional.

The last arg to `apply' must be a list.
(This is true even if it is the second arg.)
It can be nil.

* If the last arg is the second arg, then its
  elements are the args passed to FUNCTION.
  (If it is the empty list then FUNCTION must
  be nullary.)

* If the last arg is not the second arg, then
  its elements are the Nth args for FUNCTION,
  where N = 1+ the element index.  FUNCTION
  must be able to accept M args, where M = 1+
  the number of elements in the last arg.

"Must" means an error is raised if not so.


(apply)          => error
(apply ANYTHING) => error

(apply FUNCTION '(x)   ) => (funcall FUNCTION x)
 ; last arg: singleton list of args

(apply FUNCTION   x  ()) => (funcall FUNCTION x)
 ; first arg: x
 ; last arg: empty list of other args

(apply FUNCTION  ()    ) => (funcall FUNCTION)
 ; last arg: empty list of args

(apply FUNCTION  ()  ()) => (funcall FUNCTION nil)
 ; first arg nil
 ; last arg: empty list of other args




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 02:28:01 GMT) Full text and rfc822 format available.

Message #92 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: 40968 <at> debbugs.gnu.org, stefan <at> marxist.se, npostavs <at> gmail.com,
 pipcet <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 07 May 2020 05:27:05 +0300
> Date: Wed, 6 May 2020 12:28:21 -0700 (PDT)
> From: Drew Adams <drew.adams <at> oracle.com>
> Cc: Stefan Kangas <stefan <at> marxist.se>, 40968 <at> debbugs.gnu.org,
>  Noam Postavsky <npostavs <at> gmail.com>
> 
> I think (apply '(+)) should raise an error, because
> (a) the first arg is not a function and (b) it's
> missing a second arg.

That'd be an incompatible change, so it is best not to make such a
change.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 06:54:01 GMT) Full text and rfc822 format available.

Message #95 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: Stefan Kangas <stefan <at> marxist.se>, Eli Zaretskii <eliz <at> gnu.org>,
 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 7 May 2020 06:53:15 +0000
enterOn Wed, May 6, 2020 at 6:42 PM Mattias Engdegård <mattiase <at> acm.org> wrote:
> That patch is fine but perhaps incomplete, if we want (apply nil) to result in the same error when interpreted and byte-compiled.

It is incomplete. However, I've yet to find an elegant way to fix the
byte compiler and get it to emit the right error message. Can you
think of one?

(apply nil) is easy to fix, of course, but (apply
(function-returning-nil)) is more difficult.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 09:12:02 GMT) Full text and rfc822 format available.

Message #98 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: Stefan Kangas <stefan <at> marxist.se>, Eli Zaretskii <eliz <at> gnu.org>,
 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil) 
Date: Thu, 7 May 2020 11:11:00 +0200
7 maj 2020 kl. 08.53 skrev Pip Cet <pipcet <at> gmail.com>:

> It is incomplete. However, I've yet to find an elegant way to fix the
> byte compiler and get it to emit the right error message. Can you
> think of one?

You are right, that's a puzzle. No, I cannot think of an elegant way (but a few inelegant ones).
It's probably not worth the trouble; just change the error test case to

(condition-case nil
  (apply nil)
 (error 'some-error))






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 11:55:02 GMT) Full text and rfc822 format available.

Message #101 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 40968 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
 Stefan Kangas <stefan <at> marxist.se>, Pip Cet <pipcet <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 07 May 2020 07:54:10 -0400
Mattias Engdegård <mattiase <at> acm.org> writes:

> 7 maj 2020 kl. 08.53 skrev Pip Cet <pipcet <at> gmail.com>:
>
>> It is incomplete. However, I've yet to find an elegant way to fix the
>> byte compiler and get it to emit the right error message. Can you
>> think of one?
>
> You are right, that's a puzzle. No, I cannot think of an elegant way
> (but a few inelegant ones).

The obvious solution is just to leave the weird single arg form
unoptimized.  Otherwise, what about your earlier suggestion?

    (apply X) == (apply (car X) (cdr X))

> It's probably not worth the trouble; just change the error test case

By the way, bytecomp-check-1 already ignores differences between error
types.  So the test case doesn't need a condition-case at all if we
don't care about which particular error is signalled.


--- i/lisp/emacs-lisp/byte-opt.el
+++ w/lisp/emacs-lisp/byte-opt.el
@@ -1100,7 +1100,7 @@ byte-optimize-apply
   ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...).
   (if (= (length form) 2)
       ;; single-argument `apply' is special (bug#40968)
-      (byte-optimize-apply `(apply #'funcall ,(cadr form)))
+      (byte-optimize-apply `(apply (car ,(cadr form)) (cdr ,(cadr form))))
     (let ((fn (nth 1 form))
 	  (last (nth (1- (length form)) form))) ; I think this really is fastest
       (or (if (or (null last)
diff --git i/src/eval.c w/src/eval.c
index 77f54ad7b1..836be7a906 100644
--- i/src/eval.c
+++ w/src/eval.c
@@ -2373,10 +2373,11 @@ DEFUN ("apply", Fapply, Sapply, 1, MANY, 0,
   Lisp_Object fun = args[0];
   USE_SAFE_ALLOCA;
 
-  ptrdiff_t numargs = list_length (spread_arg);
+  if (nargs == 1)
+    /* Special case: FUN is really a list of (FUNCTION . ARGS).  */
+    return CALLN (Fapply, CAR (fun), CDR (fun));
 
-  if (numargs == 0 && nargs == 1)
-    wrong_type_argument (Qconsp, spread_arg);
+  ptrdiff_t numargs = list_length (spread_arg);
 
   if (numargs == 0)
     return Ffuncall (nargs - 1, args);





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 12:00:02 GMT) Full text and rfc822 format available.

Message #104 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: Mattias Engdegård <mattiase <at> acm.org>,
 Eli Zaretskii <eliz <at> gnu.org>, 40968 <at> debbugs.gnu.org,
 Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 7 May 2020 11:58:47 +0000
On Thu, May 7, 2020 at 11:54 AM Noam Postavsky <npostavs <at> gmail.com> wrote:
> -      (byte-optimize-apply `(apply #'funcall ,(cadr form)))
> +      (byte-optimize-apply `(apply (car ,(cadr form)) (cdr ,(cadr form))))

That double-evaluates (cadr form), doesn't it?

> -  ptrdiff_t numargs = list_length (spread_arg);
> +  if (nargs == 1)
> +    /* Special case: FUN is really a list of (FUNCTION . ARGS).  */
> +    return CALLN (Fapply, CAR (fun), CDR (fun));

But what if someone defines nil as a function (not serious)? (apply
nil) gets translated to (apply nil nil) which I guess will throw an
error, so that's okay.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 12:21:02 GMT) Full text and rfc822 format available.

Message #107 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Pip Cet <pipcet <at> gmail.com>
Cc: Mattias Engdegård <mattiase <at> acm.org>,
 Eli Zaretskii <eliz <at> gnu.org>, Stefan Kangas <stefan <at> marxist.se>,
 40968 <at> debbugs.gnu.org
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 07 May 2020 08:20:37 -0400
Pip Cet <pipcet <at> gmail.com> writes:

> On Thu, May 7, 2020 at 11:54 AM Noam Postavsky <npostavs <at> gmail.com> wrote:
>> -      (byte-optimize-apply `(apply #'funcall ,(cadr form)))
>> +      (byte-optimize-apply `(apply (car ,(cadr form)) (cdr ,(cadr form))))
>
> That double-evaluates (cadr form), doesn't it?

Oops, right.  Then let me go back to "don't optimize that case" (i.e.,
just return form).

>> +  if (nargs == 1)
>> +    /* Special case: FUN is really a list of (FUNCTION . ARGS).  */
>> +    return CALLN (Fapply, CAR (fun), CDR (fun));
>
> But what if someone defines nil as a function (not serious)?

Emacs doesn't care if you're serious; it has an answer ready for you
anyway:

    (defun nil () t) ;=> Cannot define ’nil’ as a function




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Thu, 07 May 2020 13:55:01 GMT) Full text and rfc822 format available.

Message #110 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattiase <at> acm.org>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
 Stefan Kangas <stefan <at> marxist.se>, Pip Cet <pipcet <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Thu, 7 May 2020 15:53:42 +0200
[Message part 1 (text/plain, inline)]
7 maj 2020 kl. 13.54 skrev Noam Postavsky <npostavs <at> gmail.com>:

> The obvious solution is just to leave the weird single arg form
> unoptimized.  Otherwise, what about your earlier suggestion?
> 
>    (apply X) == (apply (car X) (cdr X))

Yes, we are under no obligation to optimise this case in any way.

> By the way, bytecomp-check-1 already ignores differences between error
> types.  So the test case doesn't need a condition-case at all if we
> don't care about which particular error is signalled.

It seems to treat all errors as producing the value nil, but that should of course be fixed.

[bytecomp-tests.diff (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 07:38:01 GMT) Full text and rfc822 format available.

Message #113 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Mattias Engdegård <mattiase <at> acm.org>
Cc: 40968 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
 Stefan Kangas <stefan <at> marxist.se>, Noam Postavsky <npostavs <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Tue, 2 Jun 2020 07:36:26 +0000
[Message part 1 (text/plain, inline)]
On Thu, May 7, 2020 at 1:53 PM Mattias Engdegård <mattiase <at> acm.org> wrote:
> 7 maj 2020 kl. 13.54 skrev Noam Postavsky <npostavs <at> gmail.com>:
>
> > The obvious solution is just to leave the weird single arg form
> > unoptimized.  Otherwise, what about your earlier suggestion?
> >
> >    (apply X) == (apply (car X) (cdr X))
>
> Yes, we are under no obligation to optimise this case in any way.

I think there's consensus, then. I've updated the documentation, in
the patch, to state that providing two or more arguments is faster.

Patch attached.
[0001-Handle-single-argument-apply-consistently-bug-40968.patch (application/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 16:33:01 GMT) Full text and rfc822 format available.

Message #116 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Pip Cet <pipcet <at> gmail.com>, Mattias Engdegård
 <mattiase <at> acm.org>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>,
 Noam Postavsky <npostavs <at> gmail.com>
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Tue, 2 Jun 2020 09:32:04 -0700 (PDT)
> I think there's consensus, then. 

FTR, FWIW: Not a consensus that includes me.

I'm in favor of making an incompatible change,
to align Emacs with Common Lisp's more reasonable
behavior.

As I said:

  Common Lisp is unequivocally in the camp of
  requiring at least two args.

  And if Elisp follows that (which I think it should,
  unless someone can present a good use case for just
  (apply FUNCTION)), then it should raise an error if
  there are not at least two args.

The only good case presented was to say that this
would be an incompatible change.  Yes, it would,
and we should make it.

If you want to, temporarily, issue a compile-time
and runtime warning, instead of raising an error,
OK.  But Emacs should wean code and users off of
the undesirable (IMO) behavior that's been allowed.
The doc should be changed to discourage such use,
and users should be warned that it's deprecated.

Just one, non-consensual, opinion.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 16:38:01 GMT) Full text and rfc822 format available.

Message #119 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: mattiase <at> acm.org, 40968 <at> debbugs.gnu.org, stefan <at> marxist.se,
 npostavs <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Tue, 02 Jun 2020 19:36:52 +0300
> From: Pip Cet <pipcet <at> gmail.com>
> Date: Tue, 2 Jun 2020 07:36:26 +0000
> Cc: Noam Postavsky <npostavs <at> gmail.com>, Stefan Kangas <stefan <at> marxist.se>, Eli Zaretskii <eliz <at> gnu.org>, 
> 	40968 <at> debbugs.gnu.org
> 
> +@code{apply} with a single argument is special: the first element of
> +the argument, which must be a non-empty list, is called as a function
> +with the remaining elements as individual arguments.  Passing two or
> +more arguments will be faster.

This is okay, but I think the last sentence could be more explicit if
reworded like this:

  However, we recommend always passing 2 or more arguments, as the
  function works faster in that case.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 16:45:02 GMT) Full text and rfc822 format available.

Message #122 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: mattiase <at> acm.org, 40968 <at> debbugs.gnu.org, stefan <at> marxist.se,
 npostavs <at> gmail.com, pipcet <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Tue, 02 Jun 2020 19:43:38 +0300
> From: Drew Adams <drew.adams <at> oracle.com>
> Cc: Stefan Kangas <stefan <at> marxist.se>, 40968 <at> debbugs.gnu.org,
>  Noam Postavsky <npostavs <at> gmail.com>
> 
>   Common Lisp is unequivocally in the camp of
>   requiring at least two args.

We will not require minimum 2 args because that would be backward
incompatible.  I'm quite sure I already said that before.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 17:11:01 GMT) Full text and rfc822 format available.

Message #125 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Eli Zaretskii <eliz <at> gnu.org>, Drew Adams <drew.adams <at> oracle.com>
Cc: mattiase <at> acm.org, 40968 <at> debbugs.gnu.org, stefan <at> marxist.se,
 npostavs <at> gmail.com, pipcet <at> gmail.com
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Tue, 2 Jun 2020 10:10:09 -0700 (PDT)
> We will not require minimum 2 args because that would be backward
> incompatible.  I'm quite sure I already said that before.

Yes, you did, as I indicated: "The only good
case presented was to say that this would be
an incompatible change."

In expressing my non-inclusion in the purported
"consensus", that's all I did.

And "because XYZ would be backward incompatible"
has not stopped Emacs from sometimes breaking
backward compatibility.  That's a good reason,
as I said, but there are also (IMO) good reasons
not to go with that one good reason.

My suggestion is to not only "recommend always
passing 2 or more arguments" but to issue a
warning when that's not the case.  And to
deprecate that use (letting users know that at
some point it might no longer be supported).

And (IMO) the reason given to users for the
recommendation shouldn't be just because ("as")
"the function works faster in that case".




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 02 Jun 2020 18:42:01 GMT) Full text and rfc822 format available.

Message #128 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: mattiase <at> acm.org, Eli Zaretskii <eliz <at> gnu.org>, 40968 <at> debbugs.gnu.org,
 stefan <at> marxist.se, npostavs <at> gmail.com
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Tue, 02 Jun 2020 18:41:00 +0000
Drew Adams <drew.adams <at> oracle.com> writes:

>> We will not require minimum 2 args because that would be backward
>> incompatible.  I'm quite sure I already said that before.
>
> Yes, you did, as I indicated: "The only good
> case presented was to say that this would be
> an incompatible change."
>
> In expressing my non-inclusion in the purported
> "consensus", that's all I did.

Thank you for doing so. I think it's important to have a record of
whether a decision was reached by consensus or not, and I had wrongly
supposed this to be a case of the former. Sorry.

> My suggestion is to not only "recommend always
> passing 2 or more arguments" but to issue a
> warning when that's not the case.  And to
> deprecate that use (letting users know that at
> some point it might no longer be supported).

A first step towards that would be to change our existing Lisp code not
to use single-argument apply, which we could do in a follow-up patch.

> And (IMO) the reason given to users for the
> recommendation shouldn't be just because ("as")
> "the function works faster in that case".

I agree. I'll make another suggestion.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Sun, 27 Sep 2020 15:02:01 GMT) Full text and rfc822 format available.

Message #131 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: Mattias Engdegård <mattiase <at> acm.org>,
 Eli Zaretskii <eliz <at> gnu.org>, Stefan Kangas <stefan <at> marxist.se>,
 40968 <at> debbugs.gnu.org, Noam Postavsky <npostavs <at> gmail.com>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Sun, 27 Sep 2020 17:01:03 +0200
Pip Cet <pipcet <at> gmail.com> writes:

> * src/eval.c (Fapply): Handle (apply nil) without crashing.
> Document single-argument form.
> * lisp/emacs-lisp/byte-opt.el (byte-optimize-apply): Don't attempt
> to optimize single-argument apply.
> * doc/lispref/functions.texi (Calling Functions): Document
> single-argument apply.  Provide example.

It looked like most everybody was in agreement with this patch, and it
fixes the (apply nil) crash, so I've applied it to Emacs 28 now.

There was some followup on the details of the documentation, with
several suggested patches, and now that this is on the trunk, people can
go ahead and tweak it as they like, and I'm closing this bug report.

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




Added tag(s) fixed. Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sun, 27 Sep 2020 15:02:02 GMT) Full text and rfc822 format available.

bug marked as fixed in version 28.1, send any further explanations to 40968 <at> debbugs.gnu.org and Pip Cet <pipcet <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sun, 27 Sep 2020 15:02:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Sun, 27 Sep 2020 19:31:01 GMT) Full text and rfc822 format available.

Message #138 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>, Pip Cet <pipcet <at> gmail.com>
Cc: Mattias Engdegård <mattiase <at> acm.org>,
 Stefan Kangas <stefan <at> marxist.se>, 40968 <at> debbugs.gnu.org,
 Noam Postavsky <npostavs <at> gmail.com>
Subject: RE: bug#40968: 28.0.50; (apply nil)
Date: Sun, 27 Sep 2020 12:28:01 -0700 (PDT)
> It looked like most everybody was in agreement with this patch, and it
> fixes the (apply nil) crash, so I've applied it to Emacs 28 now.
> 
> There was some followup on the details of the documentation, with
> several suggested patches, and now that this is on the trunk, people can
> go ahead and tweak it as they like, and I'm closing this bug report.

Emacs Lisp should follow Common Lisp wrt `apply'
behavior.  `apply' is pretty central to Lisp,
and Common Lisp is a better spec for what Lisp
is than Emacs Lisp is.  Lots of discussion has
gone into every Common Lisp design decision.
That doesn't mean its design is perfect, of
course.  But in the case of `apply' Emacs should
follow CL.

(Just one outlier opinion.)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#40968; Package emacs. (Tue, 29 Sep 2020 03:01:02 GMT) Full text and rfc822 format available.

Message #141 received at 40968 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 40968 <at> debbugs.gnu.org, Stefan Kangas <stefan <at> marxist.se>
Subject: Re: bug#40968: 28.0.50; (apply nil)
Date: Mon, 28 Sep 2020 23:00:18 -0400
> as implying that (apply FUNCTION) is equivalent to (funcall FUNCTION)

I think the current half-broken semantics is a fairly
natural generalization:

    (apply ... ARGS)

is equivalent to

    (funcall ... ,@ARGS)

so when `...` is empty it means that

    (apply ARGS)

should be equivalent to

    (funcall ,@ARGS)
aka
    (apply (car ARGS) (cdr ARGS))

When ARGS is the empty list we should probably signal an error (just
like (apply (car ARGS) (cdr ARGS)) would, BTW).


        Stefan





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 27 Oct 2020 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 3 years and 175 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.