all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#40968: 28.0.50; (apply nil)
@ 2020-04-29 18:26 Pip Cet
  2020-04-29 18:35 ` Pip Cet
                   ` (3 more replies)
  0 siblings, 4 replies; 44+ messages in thread
From: Pip Cet @ 2020-04-29 18:26 UTC (permalink / raw)
  To: 40968

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?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 44+ messages in thread
From: Pip Cet @ 2020-04-29 18:35 UTC (permalink / raw)
  To: 40968

On Wed, Apr 29, 2020 at 6:27 PM Pip Cet <pipcet@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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 10:18 ` Mattias Engdegård
  2020-05-06 18:42 ` Mattias Engdegård
  3 siblings, 1 reply; 44+ messages in thread
From: Stefan Kangas @ 2020-05-06  1:51 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968

Pip Cet <pipcet@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06  1:51 ` Stefan Kangas
@ 2020-05-06  7:26   ` Pip Cet
  2020-05-06 11:24     ` Stefan Kangas
  2020-09-29  3:00     ` Stefan Monnier
  0 siblings, 2 replies; 44+ messages in thread
From: Pip Cet @ 2020-05-06  7:26 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 40968

On Wed, May 6, 2020 at 1:51 AM Stefan Kangas <stefan@marxist.se> wrote:
> Pip Cet <pipcet@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).





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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 10:18 ` Mattias Engdegård
  2020-05-06 10:45   ` Eli Zaretskii
  2020-05-06 11:25   ` Pip Cet
  2020-05-06 18:42 ` Mattias Engdegård
  3 siblings, 2 replies; 44+ messages in thread
From: Mattias Engdegård @ 2020-05-06 10:18 UTC (permalink / raw)
  To: Pip Cet; +Cc: Stefan Kangas, 40968

> 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?






^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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
  1 sibling, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2020-05-06 10:45 UTC (permalink / raw)
  To: 40968, mattiase, pipcet, rms; +Cc: stefan

On May 6, 2020 1:18:44 PM GMT+03:00, "Mattias Engdegård" <mattiase@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?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 10:45   ` Eli Zaretskii
@ 2020-05-06 10:57     ` Andreas Schwab
  0 siblings, 0 replies; 44+ messages in thread
From: Andreas Schwab @ 2020-05-06 10:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mattiase, 40968, stefan, rms, pipcet

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@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06  7:26   ` Pip Cet
@ 2020-05-06 11:24     ` Stefan Kangas
  2020-05-06 11:49       ` Pip Cet
  2020-09-29  3:00     ` Stefan Monnier
  1 sibling, 1 reply; 44+ messages in thread
From: Stefan Kangas @ 2020-05-06 11:24 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968

Pip Cet <pipcet@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 10:18 ` Mattias Engdegård
  2020-05-06 10:45   ` Eli Zaretskii
@ 2020-05-06 11:25   ` Pip Cet
  2020-05-06 11:49     ` Mattias Engdegård
  1 sibling, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-06 11:25 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Stefan Kangas, 40968

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

On Wed, May 6, 2020 at 10:18 AM Mattias Engdegård <mattiase@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).

[-- Attachment #2: 0001-Require-at-least-two-arguments-for-Fapply.patch --]
[-- Type: text/x-patch, Size: 3518 bytes --]

From 898af394fcbde57ca3d08e3648b62fe0b3f41911 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Wed, 6 May 2020 11:08:29 +0000
Subject: [PATCH] Require at least two arguments for Fapply

* src/eval.c (Fapply): Require at least two arguments, to prevent
crashes when (apply nil) is evaluated.
* lisp/progmodes/ebrowse.el (ebrowse-tags-loop-continue): Provide two
arguments to `apply'.
* lisp/svg.el (svg--eval-path-command): Provide two arguments to
`apply'.
* lisp/simple.el (primitive-undo): Provide two arguments to `apply'.
---
 lisp/net/telnet.el        | 3 ++-
 lisp/progmodes/ebrowse.el | 3 ++-
 lisp/simple.el            | 2 +-
 lisp/svg.el               | 3 ++-
 src/eval.c                | 2 +-
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/lisp/net/telnet.el b/lisp/net/telnet.el
index e8c0c1bbdf..b0350eacbf 100644
--- a/lisp/net/telnet.el
+++ b/lisp/net/telnet.el
@@ -109,7 +109,8 @@ telnet-revert-buffer
         (revert-buffer ignore-auto noconfirm))
     (if (or noconfirm
             (yes-or-no-p (format "Restart connection? ")))
-        (apply telnet-connect-command))))
+        (apply (car telnet-connect-command)
+               (cdr telnet-connect-command)))))
 
 (defun telnet-c-z ()
   (interactive)
diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el
index 1c9e805f03..f052266b1a 100644
--- a/lisp/progmodes/ebrowse.el
+++ b/lisp/progmodes/ebrowse.el
@@ -3612,7 +3612,8 @@ ebrowse-tags-loop-continue
   (when first-time
     (ebrowse-tags-next-file first-time tree-buffer)
     (goto-char (point-min)))
-  (while (not (apply ebrowse-tags-loop-call))
+  (while (not (apply (car ebrowse-tags-loop-call)
+                     (cdr ebrowse-tags-loop-call)))
     (ebrowse-tags-next-file)
     (message "Scanning file `%s'..." buffer-file-name)
     (goto-char (point-min))))
diff --git a/lisp/simple.el b/lisp/simple.el
index b5ba05426f..9a96ce0013 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2778,7 +2778,7 @@ primitive-undo
                      (error "Changes to be undone by function different from announced"))
                    (set-marker start-mark nil)
                    (set-marker end-mark nil))
-               (apply fun-args))
+               (apply (car fun-args) (cdr fun-args)))
              (unless (eq currbuff (current-buffer))
                (error "Undo function switched buffer"))
              (setq did-apply t)))
diff --git a/lisp/svg.el b/lisp/svg.el
index 7aadbc2359..982e2b0965 100644
--- a/lisp/svg.el
+++ b/lisp/svg.el
@@ -437,7 +437,8 @@ svg--eval-path-command
         #'svg--elliptical-arc-command)
        (extended-command (append command (list :default-relative
                                                default-relative))))
-    (mapconcat 'prin1-to-string (apply extended-command) " ")))
+    (mapconcat 'prin1-to-string (apply (car extended-command)
+                                       (cdr extended-command)) " ")))
 
 (defun svg-path (svg commands &rest args)
   "Add the outline of a shape to SVG according to COMMANDS.
diff --git a/src/eval.c b/src/eval.c
index 014905ce6d..1b9fd90482 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2358,7 +2358,7 @@ eval_sub (Lisp_Object form)
   return val;
 }
 \f
-DEFUN ("apply", Fapply, Sapply, 1, MANY, 0,
+DEFUN ("apply", Fapply, Sapply, 2, MANY, 0,
        doc: /* Call FUNCTION with our remaining args, using our last arg as list of args.
 Then return the value FUNCTION returns.
 Thus, (apply \\='+ 1 2 \\='(3 4)) returns 10.
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 11:25   ` Pip Cet
@ 2020-05-06 11:49     ` Mattias Engdegård
  0 siblings, 0 replies; 44+ messages in thread
From: Mattias Engdegård @ 2020-05-06 11:49 UTC (permalink / raw)
  To: Pip Cet; +Cc: Stefan Kangas, 40968

6 maj 2020 kl. 13.25 skrev Pip Cet <pipcet@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)))))







^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 11:24     ` Stefan Kangas
@ 2020-05-06 11:49       ` Pip Cet
  2020-05-06 13:02         ` Stefan Kangas
                           ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Pip Cet @ 2020-05-06 11:49 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 40968

On Wed, May 6, 2020 at 11:24 AM Stefan Kangas <stefan@marxist.se> wrote:
> Pip Cet <pipcet@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...





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 11:49       ` Pip Cet
@ 2020-05-06 13:02         ` Stefan Kangas
  2020-05-06 13:55           ` Pip Cet
                             ` (2 more replies)
  2020-05-06 17:46         ` Drew Adams
  2020-05-06 20:32         ` Phil Sainty
  2 siblings, 3 replies; 44+ messages in thread
From: Stefan Kangas @ 2020-05-06 13:02 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968

Pip Cet <pipcet@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 13:02         ` Stefan Kangas
@ 2020-05-06 13:55           ` Pip Cet
  2020-05-06 15:28             ` Stefan Kangas
  2020-05-06 14:03           ` Eli Zaretskii
  2020-05-06 18:00           ` Drew Adams
  2 siblings, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-06 13:55 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 40968

On Wed, May 6, 2020 at 1:02 PM Stefan Kangas <stefan@marxist.se> wrote:
> Pip Cet <pipcet@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?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 13:02         ` Stefan Kangas
  2020-05-06 13:55           ` Pip Cet
@ 2020-05-06 14:03           ` Eli Zaretskii
  2020-05-06 17:54             ` Pip Cet
  2020-05-06 18:00           ` Drew Adams
  2 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2020-05-06 14:03 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 40968, pipcet

> From: Stefan Kangas <stefan@marxist.se>
> Date: Wed, 6 May 2020 06:02:45 -0700
> Cc: 40968@debbugs.gnu.org
> 
> Pip Cet <pipcet@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?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 13:55           ` Pip Cet
@ 2020-05-06 15:28             ` Stefan Kangas
  2020-05-06 18:06               ` Pip Cet
  0 siblings, 1 reply; 44+ messages in thread
From: Stefan Kangas @ 2020-05-06 15:28 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968

Pip Cet <pipcet@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 11:49       ` Pip Cet
  2020-05-06 13:02         ` Stefan Kangas
@ 2020-05-06 17:46         ` Drew Adams
  2020-05-06 20:32         ` Phil Sainty
  2 siblings, 0 replies; 44+ messages in thread
From: Drew Adams @ 2020-05-06 17:46 UTC (permalink / raw)
  To: Pip Cet, Stefan Kangas; +Cc: 40968

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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 14:03           ` Eli Zaretskii
@ 2020-05-06 17:54             ` Pip Cet
  2020-05-06 18:09               ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-06 17:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Stefan Kangas, 40968

[-- 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


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 13:02         ` Stefan Kangas
  2020-05-06 13:55           ` Pip Cet
  2020-05-06 14:03           ` Eli Zaretskii
@ 2020-05-06 18:00           ` Drew Adams
  2020-05-06 18:28             ` Noam Postavsky
  2 siblings, 1 reply; 44+ messages in thread
From: Drew Adams @ 2020-05-06 18:00 UTC (permalink / raw)
  To: Stefan Kangas, Pip Cet; +Cc: 40968

> > (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)?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 15:28             ` Stefan Kangas
@ 2020-05-06 18:06               ` Pip Cet
  2020-05-06 19:26                 ` Drew Adams
  0 siblings, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-06 18:06 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 40968

On Wed, May 6, 2020 at 3:28 PM Stefan Kangas <stefan@marxist.se> wrote:
> Pip Cet <pipcet@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 17:54             ` Pip Cet
@ 2020-05-06 18:09               ` Eli Zaretskii
  0 siblings, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2020-05-06 18:09 UTC (permalink / raw)
  To: Pip Cet; +Cc: stefan, 40968

> From: Pip Cet <pipcet@gmail.com>
> Date: Wed, 6 May 2020 17:54:23 +0000
> Cc: Stefan Kangas <stefan@marxist.se>, 40968@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 18:00           ` Drew Adams
@ 2020-05-06 18:28             ` Noam Postavsky
  2020-05-06 19:17               ` Drew Adams
  0 siblings, 1 reply; 44+ messages in thread
From: Noam Postavsky @ 2020-05-06 18:28 UTC (permalink / raw)
  To: Drew Adams; +Cc: Stefan Kangas, 40968, Pip Cet

Drew Adams <drew.adams@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-04-29 18:26 bug#40968: 28.0.50; (apply nil) Pip Cet
                   ` (2 preceding siblings ...)
  2020-05-06 10:18 ` Mattias Engdegård
@ 2020-05-06 18:42 ` Mattias Engdegård
  2020-05-07  6:53   ` Pip Cet
  3 siblings, 1 reply; 44+ messages in thread
From: Mattias Engdegård @ 2020-05-06 18:42 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968, Stefan Kangas

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

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.



[-- Attachment #2: test.diff --]
[-- Type: application/octet-stream, Size: 746 bytes --]

diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index bfe2d06a61..65fd57b4e0 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -352,7 +352,14 @@ byte-opt-testsuite-arith-data
     ;; `substring' bytecode generation (bug#39709).
     (substring "abcdef")
     (substring "abcdef" 2)
-    (substring "abcdef" 3 2))
+    (substring "abcdef" 3 2)
+
+    ;; `apply' with single argument (bug#40968).
+    (apply '(+ 2 3 5))
+    (condition-case nil
+        (apply nil)
+      (wrong-type-argument 'wrong-arg))
+    )
   "List of expression for test.
 Each element will be executed by interpreter and with
 bytecompiled code, and their results compared.")

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 18:28             ` Noam Postavsky
@ 2020-05-06 19:17               ` Drew Adams
  2020-05-06 19:21                 ` Pip Cet
  0 siblings, 1 reply; 44+ messages in thread
From: Drew Adams @ 2020-05-06 19:17 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Stefan Kangas, 40968, Pip Cet

> >  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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 19:17               ` Drew Adams
@ 2020-05-06 19:21                 ` Pip Cet
  2020-05-06 19:28                   ` Drew Adams
  0 siblings, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-06 19:21 UTC (permalink / raw)
  To: Drew Adams; +Cc: Stefan Kangas, 40968, Noam Postavsky

On Wed, May 6, 2020 at 7:17 PM Drew Adams <drew.adams@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 18:06               ` Pip Cet
@ 2020-05-06 19:26                 ` Drew Adams
  0 siblings, 0 replies; 44+ messages in thread
From: Drew Adams @ 2020-05-06 19:26 UTC (permalink / raw)
  To: Pip Cet, Stefan Kangas; +Cc: 40968

> > > 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)?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 19:21                 ` Pip Cet
@ 2020-05-06 19:28                   ` Drew Adams
  2020-05-07  2:27                     ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Drew Adams @ 2020-05-06 19:28 UTC (permalink / raw)
  To: Pip Cet; +Cc: Stefan Kangas, 40968, Noam Postavsky

> > 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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 11:49       ` Pip Cet
  2020-05-06 13:02         ` Stefan Kangas
  2020-05-06 17:46         ` Drew Adams
@ 2020-05-06 20:32         ` Phil Sainty
  2020-05-06 21:35           ` Drew Adams
  2 siblings, 1 reply; 44+ messages in thread
From: Phil Sainty @ 2020-05-06 20:32 UTC (permalink / raw)
  To: Pip Cet; +Cc: Stefan Kangas, 40968

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






^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 20:32         ` Phil Sainty
@ 2020-05-06 21:35           ` Drew Adams
  0 siblings, 0 replies; 44+ messages in thread
From: Drew Adams @ 2020-05-06 21:35 UTC (permalink / raw)
  To: Phil Sainty, Pip Cet; +Cc: Stefan Kangas, 40968

> 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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 19:28                   ` Drew Adams
@ 2020-05-07  2:27                     ` Eli Zaretskii
  0 siblings, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2020-05-07  2:27 UTC (permalink / raw)
  To: Drew Adams; +Cc: stefan, 40968, npostavs, pipcet

> Date: Wed, 6 May 2020 12:28:21 -0700 (PDT)
> From: Drew Adams <drew.adams@oracle.com>
> Cc: Stefan Kangas <stefan@marxist.se>, 40968@debbugs.gnu.org,
>  Noam Postavsky <npostavs@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06 18:42 ` Mattias Engdegård
@ 2020-05-07  6:53   ` Pip Cet
  2020-05-07  9:11     ` Mattias Engdegård
  0 siblings, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-07  6:53 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: 40968, Stefan Kangas

enterOn Wed, May 6, 2020 at 6:42 PM Mattias Engdegård <mattiase@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-07  6:53   ` Pip Cet
@ 2020-05-07  9:11     ` Mattias Engdegård
  2020-05-07 11:54       ` Noam Postavsky
  0 siblings, 1 reply; 44+ messages in thread
From: Mattias Engdegård @ 2020-05-07  9:11 UTC (permalink / raw)
  To: Pip Cet; +Cc: 40968, Stefan Kangas

7 maj 2020 kl. 08.53 skrev Pip Cet <pipcet@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))







^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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 13:53         ` Mattias Engdegård
  0 siblings, 2 replies; 44+ messages in thread
From: Noam Postavsky @ 2020-05-07 11:54 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Stefan Kangas, 40968, Pip Cet

Mattias Engdegård <mattiase@acm.org> writes:

> 7 maj 2020 kl. 08.53 skrev Pip Cet <pipcet@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);






^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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
  1 sibling, 1 reply; 44+ messages in thread
From: Pip Cet @ 2020-05-07 11:58 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Mattias Engdegård, Stefan Kangas, 40968

On Thu, May 7, 2020 at 11:54 AM Noam Postavsky <npostavs@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-07 11:58         ` Pip Cet
@ 2020-05-07 12:20           ` Noam Postavsky
  0 siblings, 0 replies; 44+ messages in thread
From: Noam Postavsky @ 2020-05-07 12:20 UTC (permalink / raw)
  To: Pip Cet; +Cc: Mattias Engdegård, 40968, Stefan Kangas

Pip Cet <pipcet@gmail.com> writes:

> On Thu, May 7, 2020 at 11:54 AM Noam Postavsky <npostavs@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-07 11:54       ` Noam Postavsky
  2020-05-07 11:58         ` Pip Cet
@ 2020-05-07 13:53         ` Mattias Engdegård
  2020-06-02  7:36           ` Pip Cet
  1 sibling, 1 reply; 44+ messages in thread
From: Mattias Engdegård @ 2020-05-07 13:53 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Stefan Kangas, 40968, Pip Cet

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

7 maj 2020 kl. 13.54 skrev Noam Postavsky <npostavs@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.


[-- Attachment #2: bytecomp-tests.diff --]
[-- Type: application/octet-stream, Size: 2470 bytes --]

diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index bfe2d06a61..c235dd43fc 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -363,10 +363,10 @@ bytecomp-check-1
 	(byte-compile-warnings nil)
 	(v0 (condition-case nil
 		(eval pat)
-	      (error nil)))
+	      (error 'bytecomp-check-error)))
 	(v1 (condition-case nil
 		(funcall (byte-compile (list 'lambda nil pat)))
-	      (error nil))))
+	      (error 'bytecomp-check-error))))
     (equal v0 v1)))
 
 (put 'bytecomp-check-1 'ert-explainer 'bytecomp-explain-1)
@@ -374,10 +374,10 @@ bytecomp-check-1
 (defun bytecomp-explain-1 (pat)
   (let ((v0 (condition-case nil
 		(eval pat)
-	      (error nil)))
+	      (error 'bytecomp-check-error)))
 	(v1 (condition-case nil
 		(funcall (byte-compile (list 'lambda nil pat)))
-	      (error nil))))
+	      (error 'bytecomp-check-error))))
     (format "Expression `%s' gives `%s' if directly evalled, `%s' if compiled."
 	    pat v0 v1)))
 
@@ -402,10 +402,10 @@ test-byte-opt-arithmetic
     (dolist (pat byte-opt-testsuite-arith-data)
       (condition-case nil
 	  (setq v0 (eval pat))
-	(error (setq v0 nil)))
+	(error (setq v0 'bytecomp-check-error)))
       (condition-case nil
 	  (setq v1 (funcall (byte-compile (list 'lambda nil pat))))
-	(error (setq v1 nil)))
+	(error (setq v1 'bytecomp-check-error)))
       (insert (format "%s" pat))
       (indent-to-column 65)
       (if (equal v0 v1)
@@ -561,11 +561,11 @@ bytecomp-lexbind-check-1
 	(byte-compile-warnings nil)
 	(v0 (condition-case nil
 		(eval pat t)
-	      (error nil)))
+	      (error 'bytecomp-check-error)))
 	(v1 (condition-case nil
 		(funcall (let ((lexical-binding t))
                            (byte-compile `(lambda nil ,pat))))
-	      (error nil))))
+	      (error 'bytecomp-check-error))))
     (equal v0 v1)))
 
 (put 'bytecomp-lexbind-check-1 'ert-explainer 'bytecomp-lexbind-explain-1)
@@ -573,11 +573,11 @@ bytecomp-lexbind-check-1
 (defun bytecomp-lexbind-explain-1 (pat)
   (let ((v0 (condition-case nil
 		(eval pat t)
-	      (error nil)))
+	      (error 'bytecomp-check-error)))
 	(v1 (condition-case nil
 		(funcall (let ((lexical-binding t))
                            (byte-compile (list 'lambda nil pat))))
-	      (error nil))))
+	      (error 'bytecomp-check-error))))
     (format "Expression `%s' gives `%s' if directly evalled, `%s' if compiled."
 	    pat v0 v1)))
 

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-07 13:53         ` Mattias Engdegård
@ 2020-06-02  7:36           ` Pip Cet
  2020-06-02 16:32             ` Drew Adams
                               ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Pip Cet @ 2020-06-02  7:36 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Stefan Kangas, 40968, Noam Postavsky

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

On Thu, May 7, 2020 at 1:53 PM Mattias Engdegård <mattiase@acm.org> wrote:
> 7 maj 2020 kl. 13.54 skrev Noam Postavsky <npostavs@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.

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

^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  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
  2 siblings, 1 reply; 44+ messages in thread
From: Drew Adams @ 2020-06-02 16:32 UTC (permalink / raw)
  To: Pip Cet, Mattias Engdegård; +Cc: Stefan Kangas, 40968, Noam Postavsky

> 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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-06-02  7:36           ` Pip Cet
  2020-06-02 16:32             ` Drew Adams
@ 2020-06-02 16:36             ` Eli Zaretskii
  2020-09-27 15:01             ` Lars Ingebrigtsen
  2 siblings, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2020-06-02 16:36 UTC (permalink / raw)
  To: Pip Cet; +Cc: mattiase, stefan, 40968, npostavs

> From: Pip Cet <pipcet@gmail.com>
> Date: Tue, 2 Jun 2020 07:36:26 +0000
> Cc: Noam Postavsky <npostavs@gmail.com>, Stefan Kangas <stefan@marxist.se>, Eli Zaretskii <eliz@gnu.org>, 
> 	40968@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-06-02 16:32             ` Drew Adams
@ 2020-06-02 16:43               ` Eli Zaretskii
  0 siblings, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2020-06-02 16:43 UTC (permalink / raw)
  To: Drew Adams; +Cc: mattiase, stefan, 40968, npostavs, pipcet

> From: Drew Adams <drew.adams@oracle.com>
> Cc: Stefan Kangas <stefan@marxist.se>, 40968@debbugs.gnu.org,
>  Noam Postavsky <npostavs@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
       [not found]             ` <<83pnahctad.fsf@gnu.org>
@ 2020-06-02 17:10               ` Drew Adams
  2020-06-02 18:41                 ` Pip Cet
  0 siblings, 1 reply; 44+ messages in thread
From: Drew Adams @ 2020-06-02 17:10 UTC (permalink / raw)
  To: Eli Zaretskii, Drew Adams; +Cc: mattiase, stefan, 40968, npostavs, pipcet

> 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".





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-06-02 17:10               ` Drew Adams
@ 2020-06-02 18:41                 ` Pip Cet
  0 siblings, 0 replies; 44+ messages in thread
From: Pip Cet @ 2020-06-02 18:41 UTC (permalink / raw)
  To: Drew Adams; +Cc: mattiase, stefan, 40968, npostavs

Drew Adams <drew.adams@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.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-06-02  7:36           ` Pip Cet
  2020-06-02 16:32             ` Drew Adams
  2020-06-02 16:36             ` Eli Zaretskii
@ 2020-09-27 15:01             ` Lars Ingebrigtsen
  2020-09-27 19:28               ` Drew Adams
  2 siblings, 1 reply; 44+ messages in thread
From: Lars Ingebrigtsen @ 2020-09-27 15:01 UTC (permalink / raw)
  To: Pip Cet; +Cc: Mattias Engdegård, 40968, Stefan Kangas, Noam Postavsky

Pip Cet <pipcet@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





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-09-27 15:01             ` Lars Ingebrigtsen
@ 2020-09-27 19:28               ` Drew Adams
  0 siblings, 0 replies; 44+ messages in thread
From: Drew Adams @ 2020-09-27 19:28 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Pip Cet
  Cc: Mattias Engdegård, 40968, Stefan Kangas, Noam Postavsky

> 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.)





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#40968: 28.0.50; (apply nil)
  2020-05-06  7:26   ` Pip Cet
  2020-05-06 11:24     ` Stefan Kangas
@ 2020-09-29  3:00     ` Stefan Monnier
  1 sibling, 0 replies; 44+ messages in thread
From: Stefan Monnier @ 2020-09-29  3:00 UTC (permalink / raw)
  To: Pip Cet; +Cc: Stefan Kangas, 40968

> 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






^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2020-09-29  3:00 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.