Subject: 27.0.50; About the argument list of methods

From: Michael Heerdegen <[email-masked]>
Date: Wed, 20 Dec 2017 13:38:39 +0100

Hello,

(1) In (info "(elisp) Generic Functions"), there is this paragraph:

 -- Macro: cl-defmethod name [qualifier] arguments &rest [docstring]
          body
     [...]
     The ARGUMENTS list, which must be identical in all the methods that
     implement a generic function, and must match the argument list of
     that function, provides argument specializers of the form ‘(ARG
     SPEC)’, where ARG is the argument name as specified in the
     ‘cl-defgeneric’ call, and SPEC is one of the following specializer
     forms: [...]

It's not clear to me what the sentence saying the argument lists must
all be identical tries to say.  Surely they can't all be identical when
they need to specify different specializers?  Is there anything to say
at all, apart from the necessity to match the argument list of the
generic function mentioned in the next sentence?  Do I have to use the
same argument names as specified in the generic method?  That would be
suboptimal for my use case:

(2)  I want to implement a method of `seq-mapn' (see seq.el) for
streams.  It would be good if the following worked as expected:

#+begin_src emacs-lisp
(cl-defmethod seq-mapn (function (stream stream) &rest streams)
  "Map FUNCTION over the STREAMS.

Example: this prints the first ten Fibonacci numbers:

  (letrec ((fibs (stream-cons
                  1
                  (stream-cons
                   1
                   (seq-mapn #'+ fibs (stream-rest fibs))))))
    (seq-do #'print (seq-take fibs 10)))

\(fn FUNCTION STREAMS...)"
  (if (not (seq-every-p #'streamp streams))
      (cl-call-next-method)
    (cl-labels ((helper (f streams)
                        (stream-make
                         (unless (seq-some #'stream-empty-p streams)
                           (cons (apply f (mapcar #'stream-first streams))
                                 (helper f (mapcar #'stream-rest streams)))))))
      (helper function (cons stream streams)))))
#+end_src

Then C-h f seq-mapn prints the argument list of that method as

  (arg2 (arg3 stream) &rest rest)

Debugging suggested that "STREAMS..." is treated as a symbol name by the
code and rejected because it contains dots.

But even when I replace the signature specifying line at the end of the
docstring with "\(fn FUNCTION &rest STREAMS)", I get

  (arg0 (arg1 stream) &rest streams)

instead of what I have specified.  This only happens if I load the
byte-compiled code, however.

I think the documentation tries to say that I have to use exactly the
same argument names as in the generic method:

#+begin_src emacs-lisp
(cl-defmethod seq-mapn (function (sequence stream) &rest sequences)
  "Map FUNCTION over the STREAMS.

Example: this prints the first ten Fibonacci numbers:

  (letrec ((fibs (stream-cons
                  1
                  (stream-cons
                   1
                   (seq-mapn #'+ fibs (stream-rest fibs))))))
    (seq-do #'print (seq-take fibs 10)))"
  (if (not (seq-every-p #'streamp sequences))
      (cl-call-next-method)
    (cl-labels ((helper (f streams)
                        (stream-make
                         (unless (seq-some #'stream-empty-p streams)
                           (cons (apply f (mapcar #'stream-first streams))
                                 (helper f (mapcar #'stream-rest streams)))))))
      (helper function (cons sequence sequences)))))
#+end_src

That gives me for C-h f:

Implementations:

(sequence (arg1 stream) &rest sequences) in `~/software/elpa/packages/stream/stream.el'.

That's a total mess now: the first argument FUNCTION is called
"sequence", the second arg "arg1", and the third &rest argument
"sequences", which is not what I want because these must all be streams
(as tested in the method body), so this results in the most confusing
generated documentation of all.

TIA,

Michael.

In GNU Emacs 27.0.50 (build 24, x86_64-pc-linux-gnu, GTK+ Version 3.22.24)
 of 2017-12-14 built on drachen
Repository revision: 269fa5482d0761e612734b87982d7a708330bd37
Windowing system distributor 'The X.Org Foundation', version 11.0.11905000
System Description: Debian GNU/Linux testing (buster)