unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Pip Cet <pipcet@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Stefan Kangas <stefan@marxist.se>, 40968@debbugs.gnu.org
Subject: bug#40968: 28.0.50; (apply nil)
Date: Wed, 6 May 2020 17:54:23 +0000	[thread overview]
Message-ID: <CAOqdjBc2+_mMt5sn3MvFvKq8yeQcbuu5=6pTvNbiPA3CPO1d2w@mail.gmail.com> (raw)
In-Reply-To: <83lfm5kvn4.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 509 bytes --]

On Wed, May 6, 2020 at 2:04 PM Eli Zaretskii <eliz@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.

[-- Attachment #2: 0001-Handle-single-argument-apply-consistently-bug-40968.patch --]
[-- Type: text/x-patch, Size: 3926 bytes --]

From fa819045766f50c55f9bb588ecf7e0bef6a56d41 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Wed, 6 May 2020 17:46:56 +0000
Subject: [PATCH] Handle single-argument `apply' consistently (bug#40968)

---
 doc/lispref/functions.texi  |  9 +++++++++
 lisp/emacs-lisp/byte-opt.el | 29 ++++++++++++++++-------------
 src/eval.c                  |  5 +++++
 3 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index bc8ec0ef1b..054bcc169e 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -761,6 +761,10 @@ Calling Functions
 @dfn{spreads} this list so that each individual element becomes an
 argument.
 
+@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.
+
 @code{apply} returns the result of calling @var{function}.  As with
 @code{funcall}, @var{function} must either be a Lisp function or a
 primitive function; special forms and macros do not make sense in
@@ -788,6 +792,11 @@ Calling Functions
 (apply 'append '((a b c) nil (x y z) nil))
      @result{} (a b c x y z)
 @end group
+
+@group
+(apply '(+ 3 4))
+     @result{} 7
+@end group
 @end example
 
 For an interesting example of using @code{apply}, see @ref{Definition
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 4f72251aed..32e53bb7e9 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1098,19 +1098,22 @@ byte-optimize-funcall
 (defun byte-optimize-apply (form)
   ;; If the last arg is a literal constant, turn this into a funcall.
   ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...).
-  (let ((fn (nth 1 form))
-	(last (nth (1- (length form)) form))) ; I think this really is fastest
-    (or (if (or (null last)
-		(eq (car-safe last) 'quote))
-	    (if (listp (nth 1 last))
-		(let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
-		  (nconc (list 'funcall fn) butlast
-			 (mapcar (lambda (x) (list 'quote x)) (nth 1 last))))
-	      (byte-compile-warn
-	       "last arg to apply can't be a literal atom: `%s'"
-	       (prin1-to-string last))
-	      nil))
-	form)))
+  (if (= (length form) 2)
+      ;; single-argument `apply' is special (bug#40968)
+      (byte-optimize-apply `(apply #'funcall ,(cadr form)))
+    (let ((fn (nth 1 form))
+	  (last (nth (1- (length form)) form))) ; I think this really is fastest
+      (or (if (or (null last)
+		  (eq (car-safe last) 'quote))
+	      (if (listp (nth 1 last))
+		  (let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
+		    (nconc (list 'funcall fn) butlast
+			   (mapcar (lambda (x) (list 'quote x)) (nth 1 last))))
+	        (byte-compile-warn
+	         "last arg to apply can't be a literal atom: `%s'"
+	         (prin1-to-string last))
+	        nil))
+	  form))))
 
 (put 'funcall 'byte-optimizer 'byte-optimize-funcall)
 (put 'apply   'byte-optimizer 'byte-optimize-apply)
diff --git a/src/eval.c b/src/eval.c
index 014905ce6d..77f54ad7b1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2361,6 +2361,8 @@ eval_sub (Lisp_Object form)
 DEFUN ("apply", Fapply, Sapply, 1, MANY, 0,
        doc: /* Call FUNCTION with our remaining args, using our last arg as list of args.
 Then return the value FUNCTION returns.
+With a single argument, call the argument's first element using the
+other elements as args.
 Thus, (apply \\='+ 1 2 \\='(3 4)) returns 10.
 usage: (apply FUNCTION &rest ARGUMENTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
@@ -2373,6 +2375,9 @@ DEFUN ("apply", Fapply, Sapply, 1, MANY, 0,
 
   ptrdiff_t numargs = list_length (spread_arg);
 
+  if (numargs == 0 && nargs == 1)
+    wrong_type_argument (Qconsp, spread_arg);
+
   if (numargs == 0)
     return Ffuncall (nargs - 1, args);
   else if (numargs == 1)
-- 
2.26.2


  reply	other threads:[~2020-05-06 17:54 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-29 18:26 bug#40968: 28.0.50; (apply nil) Pip Cet
2020-04-29 18:35 ` Pip Cet
2020-05-06  1:51 ` Stefan Kangas
2020-05-06  7:26   ` Pip Cet
2020-05-06 11:24     ` Stefan Kangas
2020-05-06 11:49       ` Pip Cet
2020-05-06 13:02         ` Stefan Kangas
2020-05-06 13:55           ` Pip Cet
2020-05-06 15:28             ` Stefan Kangas
2020-05-06 18:06               ` Pip Cet
2020-05-06 19:26                 ` Drew Adams
2020-05-06 14:03           ` Eli Zaretskii
2020-05-06 17:54             ` Pip Cet [this message]
2020-05-06 18:09               ` Eli Zaretskii
2020-05-06 18:00           ` Drew Adams
2020-05-06 18:28             ` Noam Postavsky
2020-05-06 19:17               ` Drew Adams
2020-05-06 19:21                 ` Pip Cet
2020-05-06 19:28                   ` Drew Adams
2020-05-07  2:27                     ` Eli Zaretskii
2020-05-06 17:46         ` Drew Adams
2020-05-06 20:32         ` Phil Sainty
2020-05-06 21:35           ` Drew Adams
2020-09-29  3:00     ` Stefan Monnier
2020-05-06 10:18 ` Mattias Engdegård
2020-05-06 10:45   ` Eli Zaretskii
2020-05-06 10:57     ` Andreas Schwab
2020-05-06 11:25   ` Pip Cet
2020-05-06 11:49     ` Mattias Engdegård
2020-05-06 18:42 ` Mattias Engdegård
2020-05-07  6:53   ` Pip Cet
2020-05-07  9:11     ` Mattias Engdegård
2020-05-07 11:54       ` Noam Postavsky
2020-05-07 11:58         ` Pip Cet
2020-05-07 12:20           ` Noam Postavsky
2020-05-07 13:53         ` Mattias Engdegård
2020-06-02  7:36           ` Pip Cet
2020-06-02 16:32             ` Drew Adams
2020-06-02 16:43               ` Eli Zaretskii
2020-06-02 16:36             ` Eli Zaretskii
2020-09-27 15:01             ` Lars Ingebrigtsen
2020-09-27 19:28               ` Drew Adams
     [not found] <<CC40D602-5027-40A7-9BAB-1AADC9E4BDAE@acm.org>
     [not found] ` <<CAOqdjBfj6AExvem5WWLfMiw4fEsY-xUUmosV+fj9CaPgWM16ag@mail.gmail.com>
     [not found]   ` <<ECEC9424-919F-4364-9294-381C8751921A@acm.org>
     [not found]     ` <<874kssm04d.fsf@gmail.com>
     [not found]       ` <<6ADF0807-7EBD-4054-8579-4D9AD3065D51@acm.org>
     [not found]         ` <<CAOqdjBdQne3RFTjg4hej40L5aeBx6vbGp6nXKx2TwPkLPf5NPw@mail.gmail.com>
     [not found]           ` <<fabfb1fd-4da1-4e72-90c9-333532011a48@default>
     [not found]             ` <<83pnahctad.fsf@gnu.org>
2020-06-02 17:10               ` Drew Adams
2020-06-02 18:41                 ` Pip Cet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOqdjBc2+_mMt5sn3MvFvKq8yeQcbuu5=6pTvNbiPA3CPO1d2w@mail.gmail.com' \
    --to=pipcet@gmail.com \
    --cc=40968@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=stefan@marxist.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).