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..."))))
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.
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))
Related
I'm just learning emacs and came across a configuration that demonstrates quite a bit of the functionality I want in my own configuration. It uses init.el as an entry point to an org file that handles the bulk of the configuration with extensive documentation. I am confused by the following function:
(put 'after-save-hook 'safe-local-variable
(lambda (value) (equal value '(org-babel-tangle t))))
What I think I understand is that this puts the value of the lambda expression into the property list of after-save-hook under the property name safe-local-variable, and that a value is safe if, when passed to the safe-local-variable-p function it returns a non-nil value. This lambda then appears to do an equality comparison between value and the list (org-babel-tangle t), so presumably this means that value is safe only when it's equal to the list (org-babel-tangle t)?
What I am having trouble understanding is twofold. First, where is the lambda getting value from? Second, what is this all actually doing? Neither the documentation I could find on after-save-hook nor org-babel-tangle clarified this for me. The author's comments say "Mark safe variables early so that tangling won't break," but I still don't get it.
The anonymous function with argument value gets its arg from the value of after-save-hook.
after-save-hook is a variable. Its value is a list of hooks.
This code puts the anonymous function as the safe-local-variable property value of symbol after-save-hook, so that when after-save-hook is processed as to see if it is a safe local variable, that function is called. The function is called on the current value of the variable, after-save-hook.
See the Elisp manual, node File Local Variables.
The reason for this is that the file DESKTOP.org starts with this line:
# -*- after-save-hook: (org-babel-tangle t); -*-
That is, when you open that file in Emacs, the local value of after-save-hook becomes (org-babel-tangle t). So whenever you save that file, it's going to call the function org-babel-tangle without any arguments, in order to generate a few shell scripts, e.g. scripts/screenshot.region.sh. The value t in a hook variable means that after calling all the functions in the local value of the hook variable, run-hooks is going to look at the global value of after-save-hook and call any functions listed there as well.
Obviously, allowing any file to specify arbitrary Lisp code to be run would be a security hole equaled only by Microsoft Word macros, so by default file-local settings for risky variables are ignored. Since we know this particular value is safe,* we use the safe-local-variable trick you're asking about. As per the documentation:
You can specify safe values for a variable with a
‘safe-local-variable’ property. The property has to be a function of
one argument; any value is safe if the function returns non-‘nil’ given
that value.
So that's what we have here:
(lambda (value) (equal value '(org-babel-tangle t)))
It is a function that takes one argument, and checks that the argument is equal to the specific value we want to allow. safe-local-variable-p is going to call this function on the specified file-local value, and only allow it if the function returns non-nil. Thus, value is going to be the value that is about to be assigned to after-save-hook. We can see that in action in M-x ielm:
*** Welcome to IELM *** Type (describe-mode) for help.
ELISP> (setq my-function (lambda (value) (equal value '(org-babel-tangle t))))
(lambda
(value)
(equal value
'(org-babel-tangle t)))
ELISP> (funcall my-function '(org-babel-tangle t))
t
ELISP> (funcall my-function 'something-else)
nil
* Is this safe, though?... If an attacker can get you to download a specially crafted file and run org-babel-tangle on it, they can overwrite arbitrary files in the file system using the privileges of your user. It's not what's happening in this case, just something to be aware of.
I was experimenting with interplay between Emacs lexical scoping (new feature of Emacs 24) and add-to-list and found the interplay confusing and I don't know how to make sense of it. Here is a minimal example, except I use set instead of add-to-list. (set is similar to add-to-list in that it usually takes a quoted variable name)
(eval
'(progn
(setq a "global")
(let ((a "apple"))
(defun my-print-a ()
(print a)
(set 'a "by set")
(print a))
(setq a "mature apple"))
(let ((a "banana"))
(my-print-a))
(print a))
t) ;; t for lexical scoping
Above code prints "mature apple", "mature apple", "by set" in order. The first print result, "mature apple", is as expected for lexical scoping (with support for lexical closures), nothing surprising to see here. But the results of the second and the third print are surprising to me. It's as if (set 'a "by set") is only recognizing and affecting the global binding of the name a.
Is this an intended behavior? Or is this a bug? If intended, how does one make sense of this behavior?
Am I right in assuming that it's always the global binding that set affects as long as lexical scoping is on?
With (eval '(progn ...) nil), things work as expected of dynamic scoping and the behavior of (set 'a ...) is the same as that of (setq a ...) in that case. Only when one uses lexical scoping and a quoted variable together, this gotcha shows up.
Update:
it seems to be an intended behavior according to the manual. On Void Variables, manual says
Under lexical binding rules, the value cell only holds the variable's global value, i.e. the value outside of any lexical binding construct. When a variable is lexically bound, the local value is determined by the lexical environment; the variable may have a local value if its symbol's value cell is unassigned.
and on Lexical Binding
functions like symbol-value, boundp, and set only retrieve or modify a variable's dynamic binding (i.e. the contents of its symbol's value cell).
symbol-value, boundp, set are functions usually called with quoted variable names ((symbol-value 'var) (boundp 'var) (set 'var 123)). These functions only get or set a symbol's value cell, and under lexical binding rules, the value cell only holds the global value. So under lexical binding, use of quoted variables only get or set global values (unless the variable is a special variable). Although it still seems odd in that the result is neither lexical (apple) nor dynamic (banana).
The code is not written in the way that Emacs expects a lexical-scoping-enabled program to be written.
http://www.gnu.org/software/emacs/manual/html_node/elisp/Definitions.html
defvar and defconst are special forms that define a symbol as a global variable—a variable that can be accessed at any point in a Lisp program.
(...)
In principle, you can assign a variable value to any symbol with setq, whether not it has first been defined as a variable. However, you ought to write a variable definition for each global variable that you want to use; otherwise, your Lisp program may not act correctly if it is evaluated with lexical scoping enabled.
http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html
Note that functions like symbol-value, boundp, and set only retrieve or modify a variable's dynamic binding (i.e. the contents of its symbol's value cell). Also, the code in the body of a defun or defmacro cannot refer to surrounding lexical variables.
http://www.gnu.org/software/emacs/manual/html_node/elisp/Setting-Variables.html
Special Form: setq [symbol form]...
This special form is the most common method of changing a variable's value. (...) The current binding of the symbol is changed.
(...)
Function: set symbol value
This function puts value in the value cell of symbol.
(...)
When dynamic variable binding is in effect (the default), set has the same effect as setq, apart from the fact that set evaluates its symbol argument whereas setq does not. But when a variable is lexically bound, set affects its dynamic value, whereas setq affects its current (lexical) value.
If we add defvar that defines a as a global variable, we can see that all the references to a in the my-print-a function turn out to be dynamically bound as the manual explains:
(eval
'(progn
(defvar a nil)
(setq a "global")
(let ((a "apple"))
(defun my-print-a ()
(print a) ; "banana"
(set 'a "by set")
(print a)) ; "by set"
(setq a "mature apple"))
(let ((a "banana"))
(my-print-a))
(print a)) ; "global"
t)
I'm working on a toy lisp implementation, inspired by picolisp. Thus there are only dynamically scoped variables(plus file local variables). Recently I wondered, whether it is possible to add closures to the language. Currently the bindings of all variables referenced in a lambda expression are stored in the expression's activation record (i.e. on a explicit stack for the lisp implementation) and restored when the execution of that lambda expression is finished. Closures should be possible by saving the bindings of the symbols referenced by the closure, then restore the bindings the closure carries for the duration of the closure's execution and afterwards restoring the previous bindings.
Now to the question: is this equivalent to lexical closures?
It is a good simulation of lexical closures depending on what you mean by saving the bindings..., it is not quite the same.
(defun closure ()
(let ((var "first value"))
(format #t "Value is ~a" var)
(let ((closure (lambda () (format #t "Value inside the closure ~a" var))))
(setf var "second value")
(funcall closure))))
If you save the value of the binding for the closure, you get the following output:
Value is first value
Value inside the closure first value
That means that your closure does not see the mutation of var. Because it only saved the current value when building the closure.
If you save the complete binding (the variable and its value), and all references to this variable uses the same binding (variable and value), then you get lexical closures.
It is not particularly efficient though as there is a lot of copying happening when you invoke a closure.
The R5RS spec states that as part of the requirements for a macro defined using syntax-rules:
If a macro transformer inserts a free reference to an identifier, the reference refers to the binding that was visible where the transformer was specified, regardless of any local bindings that may surround the use of the macro.
I am trying to understand how this works in practice. So for example, if I have the following code:
(define var 'original)
(define-syntax test-var
(syntax-rules (var)
((_ var)
var)
((_ pattern-var)
'no-match)))
I would expect the following, if executed immediately after, to evaluate to original, which it does:
(test-var var)
And I would expect this one to be no-match since the var introduced into scope prior to test-var does not match the binding of var at macro definition:
(let ((var 1)) (test-var var))
However the following example has me puzzled:
(define var 'new-var)
(test-var var)
In Chicken Scheme, this evaluates to new-var. I would have expected it to be no-match for the same reasons as the previous (let) example. I thought that perhaps this was an issue with using define twice, but the result is still new-var even if I use (set! var 'new-var)
Does anyone have any insight as to what is going on here? What should happen per R5RS?
This is the usual trick that Schemes have when dealing with redefinitions on the REPL -- treating them as a mutation for the existing binding. So the second define is not really creating a new binding, and instead it just set!s the existing one.
numberp is a predicate in Lisp, and (numberp 1) returns T as expected. But if I only type numberp in the console, it prompts that the variable name is undefined.
What's the difference between these 2?
The question is slightly wrong already.
We are talking about different things in Common Lisp:
symbol : that's a data structure in Lisp. A symbol is a data object with a name, a value, a function, a package and possibly more.
In Common Lisp the symbol can have both a value and a function (or macro).
a variable is an identifier for a value in Lisp code
There are top-level variables defined by DEFVAR and DEFPARAMETER. There are also local variables defined by LAMBDA, DEFUN, LET, LET* and others.
(defun foo (i-am-a-variable) ...)
(defparameter *i-am-a-global-variable* ...)
a named function is an identifier for a function in Lisp code. Named functions are introduced on the top-level by DEFUN, DEFGENERIC and DEFMETHOD. There are also local named functions defined by FLET and LABELS.
Example:
(defun i-am-a-function (foo) ...)
(flet ((i-am-a-function (foo) ...)) ...)
To further complication function names and variable names are symbols in the source code.
Example:
(type-of (second '(defun foo () nil))) --> SYMBOL
Let's look at functions and variables:
(defun foo ()
(let ((some-name 100))
(flet ((some-name (bar) (+ bar 200)))
(+ some-name (some-name some-name)))))
Above code uses a variable and a function with the same symbol in the source code. Since functions and variables have their own namespace, there is no collision.
(+ some-name (some-name some-name))
Above then means we add the variable to the result of the function call on the variable.
This has the practical effect that you can do something like this:
(defun parent (person) ...)
(defun do-something (parent)
(parent parent))
You don't have to fear that your local variable names will shadow a global (or local) function. They simply are in different namespaces.
In Scheme there is only one namespace and we have to write
(define (foo lst) (list 'a lst 'n))
where in Common Lisp we can write:
(defun foo (list) (list 'a list 'n))
In Common Lisp there is no need to write lst instead of list - because there is no clash between the local variable list and the global function list.
Accessing the other namespace
To get a function object stored in a variable you can use FUNCTION.
(let ((my-function (function numberp)))
(funcall my-function 10))
(function foo) can be written shorter as #'foo.
FUNCALL calls a function object.
OTOH, if you want to store a function object from a variable in the function namespace, there is only one way:
(setf (symbol-function 'foo) my-function)
It is also necessary that the object is really a function and not something else (a number, a string, ...). Otherwise you'll see an error.
The side effect of this is that a Common Lisp never has to check if in (foo bar) the FOO is really a function. There is no possibility that it can be other than a function or undefined.
Functions and variables live in different namespaces in Common Lisp.
So when you use a name in a position where a function is expected (i.e. at the head of a list that is being evaluated), it looks for a function (or macro) with that name. If you use the same name at a position where a variable is expected, it looks for a variable with that name.
In your case there is a function named numberp, but not variable named numberp, so the second case causes an error.
One of the differences between Scheme (one Lisp dialect, so to speak) and Common Lisp is that in Scheme, there is one namespace for variables and functions, whereas in CL, there are two separate namespaces.
Thus, in Scheme, "define" sets this one-and-only name-to-value assoc, whereas in CL, there is "define" for the value and "defun" for the function association.
So, in CL you can:
(define foo ...something...)
(defun foo ...somethingElse...)
to confuse the reader.
In Scheme, there is only one:
(define foo something)
If this is good or bad has been an almost religious dispute in the past...