unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Klaus-Dieter Bauer <bauer.klaus.dieter@gmail.com>
To: emacs-devel@gnu.org
Subject: Can the byte-compiler check whether functions passed by name are defined?
Date: Mon, 29 Jul 2013 12:35:03 +0200	[thread overview]
Message-ID: <CANtbJLGK91q88K-A_a=Q_XSEX0eRN4zS1Ab=jJ-YUC3+cObQ6Q@mail.gmail.com> (raw)

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

Hello!


TL;DR
=====

Is there some possibility to make the byte-compiler check,
whether functions passed to higher-order functions as a symbol are
defined at compile-time, e.g. my-function-1 in

    (mapcar 'my-function-1 some-list)?

I know some (intrusive) solutions, but if there is a built-in solution
or at least an elegant solution I'd strongly prefer that one.


My use-case
===========

When I do programming in emacs lisp, I typically start top-down. In
that process I introduce functions about whose implementation I intend
to think later, and rely on the byte-compiler for pointing out
functions to be implemented.

That approach however breaks down, when using higher-order functions.
If I have a function

    (defun my-function (strings)
      (append (list "start")
      (mapcar 'my-function-1 strings)
      (list "end")))

the byte-compiler will not tell me, that the function is undefined.
What is normally a byte-compiler warning is now a runtime error. So
far I don't know a //good// workaround, though I tried some:

1. Don't use a name, write a lambda in-place. Downside: Seriously
   reduces readability when `my-function-1' is complex or especially,
   when it contains something like

       (mapcar 'my-function-1
         (delete nil
           (mapcar 'my-function-2 strings)))

2. Use a combination of function and variable

       ...
       (mapcar my-function-1 strings)
       ...
       (defconst my-function-1 (lambda () ...

   Downside: Uncommon, therefore probably hard to read for anyone else
   (and probably for myself a year later).

3. Wrap into a lambda.

       (mapcar (lambda (e) (my-function-1 e)) strings)

   Upside: When `my-function-1' is a general function that needs
   more than one argument, this construct seems to be an elegant
   solution when using lexical binding.

   Downside: When, like here, it takes only one argument, it is more
   likely unnecessarily confusing.

4. Wrap the higher-order functions into macros that do the check at
   compile time.

   Downside: I cannot think of a way, that

   - Preserves the interface, including parameter names, and thus
     the readbility of the `describe-function' text.
   - Is future proof in that it doesn't require changing the wrapper
     code when the interface of the function is changed in a
     backward-compatible way.
   - Doesn't interfere with the runtime behaviour of interpreted code
     (e.g. raising warnings only during compilation, but not when
     interpreting the code).


kind regards, Klaus

[-- Attachment #2: Type: text/html, Size: 3809 bytes --]

             reply	other threads:[~2013-07-29 10:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-29 10:35 Klaus-Dieter Bauer [this message]
2013-07-29 15:21 ` Can the byte-compiler check whether functions passed by name are defined? Stefan Monnier
2013-07-31 13:44   ` Klaus-Dieter Bauer
2013-07-31 17:49     ` Stefan Monnier
2013-07-31 18:01       ` Sebastian Wiesner
2013-08-01 20:31         ` Stefan Monnier
2013-08-04 18:41           ` Klaus-Dieter Bauer
2013-08-04 21:11             ` Stefan Monnier
2013-08-05  8:52               ` Klaus-Dieter Bauer
2013-08-05 14:35                 ` Stefan Monnier
2013-08-05 18:17                   ` Klaus-Dieter Bauer
2013-08-07 11:27                     ` Klaus-Dieter Bauer
2013-08-07 14:41                     ` Stefan Monnier
2013-08-07 15:11                       ` Klaus-Dieter Bauer
2013-08-07 15:21                         ` Stefan Monnier
2013-08-07 17:34                           ` Stefan Monnier
2013-08-07 21:11                             ` Glenn Morris
2013-08-07 21:59                               ` Glenn Morris
2013-08-08  1:25                                 ` Stefan Monnier
2013-08-08  8:44                                   ` Klaus-Dieter Bauer
2013-08-08 13:07                                     ` Stefan Monnier
2013-08-07 19:59                           ` Klaus-Dieter Bauer
2013-08-07 21:14                             ` Stefan Monnier

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='CANtbJLGK91q88K-A_a=Q_XSEX0eRN4zS1Ab=jJ-YUC3+cObQ6Q@mail.gmail.com' \
    --to=bauer.klaus.dieter@gmail.com \
    --cc=emacs-devel@gnu.org \
    /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).