2

It it possible to declare functions whose names are only available in the scope of another function, similar to let?

e.g.:

(defun my-fn (x y) 
  (let ((my-local-fn (lambda (a b) (message "%S" (- a b)))))
    (my-local-fn x y)
    (my-local-fn y x))
  • 2
    @Dan answered your question. In addition, in Emacs Lisp, as in Common Lisp, you can nest defun (or cl-defun) definitions, but that does not control definition scope: each defun is interpreted globally. This differs from Scheme's define, for example. See stackoverflow.com/a/34893747/729907 (Common Lisp question). – Drew Jul 12 at 23:16
  • It's rare for code to actually use this. In practice you'll see packages to define a global helper function instead. – wasamasa Jul 13 at 9:38
6

You can also do it without resorting to cl-lib as follows:

(defun my-fn (x y) 
  (let ((my-local-fn (lambda (a b) (message "%S" (- a b)))))
    (funcall my-local-fn x y)
    (funcall my-local-fn y x))
  • Is the function definition hold in the value cell of the symbol? – Fólkvangr Jul 13 at 14:09
  • Only if you're not using lexical-binding. – Stefan Jul 13 at 14:18
5

You can use cl-flet or cl-labels from cl-lib. The docstrings:

(cl-flet ((FUNC ARGLIST BODY...) ...) FORM...)

  Probably introduced at or before Emacs version 24.3.

Make local function definitions.
Each definition can take the form (FUNC EXP) where
FUNC is the function name, and EXP is an expression that returns the
function value to which it should be bound, or it can take the more common
form (FUNC ARGLIST BODY...) which is a shorthand
for (FUNC (lambda ARGLIST BODY)).

FUNC is defined only within FORM, not BODY, so you can’t write
recursive function definitions.  Use ‘cl-labels’ for that.  See
info node ‘(cl) Function Bindings’ for details.



(cl-labels ((FUNC ARGLIST BODY...) ...) FORM...)

  Probably introduced at or before Emacs version 24.3.

Make local (recursive) function definitions.
Each definition can take the form (FUNC ARGLIST BODY...) where
FUNC is the function name, ARGLIST its arguments, and BODY the
forms of the function body.  FUNC is defined in any BODY, as well
as FORM, so you can write recursive and mutually recursive
function definitions.  See info node ‘(cl) Function Bindings’ for
details.
2

Note: see Stefan's anwser.

It seems that local functions are not a native feature of the language. The GNU Reference Manual does not cover "local functions" or mention it.

(defun foo (a b)
  (+ a b))

(let (foo)
  (setq val (symbol-value 'foo))
  (symbol-function 'foo))

(symbol-function 'foo) returns (lambda (a b) (+ a b)) whereas (symbol-value 'foo) returns nil.

Nevertheless, this feature is provided by the GNU Emacs Common Lisp Emulation (c.f. Function Bindings) which is a compatibility extension with Common Lisp for Elisp.

(cl-flet ((func (a b) (+ a b)))
  (func 1 1))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.