Consider the following metacode:
;;; -*- lexical-binding: t -*-
(defvar var1 ...)
(defvar var2 ...)
(defun main ()
"Main entry point" ...)
(defun func1 ...)
(defun func2 ...)
...
(defun funcn ...)
(defun f ...)
(defun g ...)
If a variable is relevant to the whole logic of your program, you make it visible to all functions declaring it global in defvar
. If a variable is relevant only to some functions, say f
and g
above, you make it visible to the latter functions only. This is known as friendship, avoids "cluttering" the global space and can be easily implemented in elisp like follows:
;;; -*- lexical-binding: t -*-
(defun main ()
"Main entry point"
(message "f: %s; g: %s" (f) (g)))
(let ((x 0))
(defun f () (1+ x))
(defun g () (+ 2 x)))
Now f
and g
share the same variable x
without using the global space, that is without (defvar x 0)
.
Unfortunately the compiler wrongly complains:
Warning: the following functions are not known to be defined: f, g
One can use without problems the byte-compiled code, but in so far as you want to use the compiler to lint your code, false positives are not welcomed. Plus, the let-bound variable x
becomes static.
I would like to find an alternative approach avoiding warnings and static variables.
What I am not looking for
I am aware of this question. Will Kunkel receives the same warning, however he has a totally different objective: he "want(s) to get the effect of a static variable by using defun inside of let".
I have not one but several defuns and want to share variables, not make them static.
IMHO the proposed let-bound variables in defalias are better avoided because calling twice the defalias function may cause an error difficult to spot as it does not stop your program, it just produces a biased output. Of course, this does not apply in specific cases when you explicitly need your function to keep its value between invocations.