Lorem Ipsum
Lorem Ipsum

Reputation: 4564

Local to `let` versus local to a function

In another question regarding local variable definitions in Elisp, both respondents advise that let is appropriate and emphasize that it will not define the variable to be local to the function. The variable is local only to the let statement.

What is the distinction between local to let and local to the function? Is there another construct which would define the variable for the scope of the function?

The function using a let statement looks this:

(defun test-search (string)
  "Searches for STRING in document.
Displays message 'Found!' or 'Not found...'. Places point after word 
when found; fixed otherwise."
  (interactive "sEnter search word: ")
  (let ((found (save-excursion
         (beginning-of-buffer)
         (search-forward string nil t nil))))
    (if found
        (progn
          (goto-char found)
          (message "Found!"))
      (message "Not found..."))))

Upvotes: 4

Views: 105

Answers (2)

phils
phils

Reputation: 73355

What is the distinction between local to let and local to the function?

The question is slightly open to interpretation, but here I am interpreting "local to the function" as meaning that code which is not part of the function cannot see the variable, and by default in Emacs that is not the case for a let binding (or indeed for variable bindings in general).

To understand in detail you need to understand the difference between dynamic binding and lexical binding (and there are good explanations of this elsewhere, so you can follow this up yourself). To briefly demonstrate the difference, however, consider the following functions:

(defun func1 ()
  (let ((foo 42))
    (func2)))

(defun func2 ()
  (bound-and-true-p foo))

The result of func1 is the result of func2, which in turn depends on whether a variable foo is visible to the latter function.

Under the default dynamic binding, calling func1 will return 42, because the scope of the binding of foo is the duration of the let, which incorporates the call to func2.

Under lexical binding, calling func1 will return nil, because foo (which has not otherwise been declared dynamic) has a binding which is local to func1 and therefore func2 cannot see it).

I'm actually being slightly misleading when talking about "local to the function" with respect to the above example, as the scope of the foo binding is strictly the scope of the let form rather than the scope of the function. The behaviour is not restricted to only let bindings though, so we could also use the following example, comparing the result of (func3 42) under dynamic and lexical binding:

(defun func3 (foo)
  (func4))

(defun func4 ()
  (bound-and-true-p foo))

Upvotes: 0

Stefan
Stefan

Reputation: 28581

Since the let makes up the whole body of your function in your example, your "variables local to let" are indistinguishable from "variables local to the function".

For that reason, no there is no separate construct to introduce variables local to a function. let is that construct, which can be used for variables valid over the whole function, or for variables valid over a small subset, depending on where you place the let.

Upvotes: 4

Related Questions