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.
f
andg
are not local definitions. This question is about how to make the byte compiler aware of the fact that they have been defined by the timeg
is invoked in the call tomessage
.(let ((x 0)) (defun f ()...) (defun g ()...))
thex
is every bit as "static" as in thedefalias
case. So it seems your question is still confused/confusing.x
.