GNU bug report logs - #65797
`buffer-match-p` should not use `func-arity`

Previous Next

Package: emacs;

Reported by: Joseph Turner <joseph <at> breatheoutbreathe.in>

Date: Thu, 7 Sep 2023 07:56:02 UTC

Severity: normal

Found in version 29.0.92

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

Full log


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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Joseph Turner <joseph <at> breatheoutbreathe.in>
Cc: 65797 <at> debbugs.gnu.org
Subject: Re: bug#65797: 29.0.92; func-arity should not return (0 . many)
 with apply-partially
Date: Thu, 07 Sep 2023 11:50:16 -0400
retitle 65797 `buffer-match-p` should not use `func-arity`
thanks

> (match-buffers (apply-partially #'local-variable-p 'foo))

Note that this call is incorrect according to the docstring of
`buffer-match-p`, which says:

    CONDITION is either:
    [...]
    - a predicate function that takes BUFFER-OR-NAME and ARG as
      arguments, and returns non-nil if the buffer matches,

IOW, you have to pass a function that accepts 2 arguments, whereas your
(apply-partially #'local-variable-p 'foo) only accepts one.

The Texinfo docs instead say:

    @item
    A predicate function, which should return non-@code{nil} if the buffer
    matches.  If the function expects one argument, it is called with
    @var{buffer-or-name} as the argument; if it expects 2 arguments, the
    first argument is @var{buffer-or-name} and the second is @var{arg}
    (or @code{nil} if @var{arg} is omitted).

but in general we can't reliably decide whether "the function expects
one argument", so we can't implement the above promise in a reliable way.
`apply-partially` is just one case where this shows up, but the problem
is much more general.
`buffer-match-p` uses the `func-arity` hack to try to make it work with
some functions of 1 argument, but it's just a hack.

We should get rid of this hack.  Here are some possible replacements
(by order of my preference):

- Replace `&optional arg` with `&rest args` and pass those args via
  `apply`, so the number of args passed doesn't depend on the function
  but on the caller.
- Always pass both args to the function (i.e. as documented in the
  docstring).
- Get rid of `&optional arg` altogether.
  AFAICT, most callers don't use it, but it's used for
  `display-buffer-alist`, so it would have further consequences there :-(
- Use a hack like

      (condition-case nil (funcall condition buffer-or-name arg)
        (wrong-number-of-arguments (funcall condition buffer-or-name)))

  which handles the arity mismatch a bit more reliably, but at the cost of
  occasionally running the function twice.


        Stefan





This bug report was last modified 1 year and 217 days ago.

Previous Next


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