emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Can the byte-compiler check whether functions passed by name are defined


From: Klaus-Dieter Bauer
Subject: Can the byte-compiler check whether functions passed by name are defined?
Date: Mon, 29 Jul 2013 12:35:03 +0200

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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]