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.
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.
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))
I am still interested in the question which has been answered.
continuation in common lisp by macros — regarding an implemetation in OnLisp
What will happen if Paul Graham's assumption is correct especially when change from (A 5) to (B 1)? What is cont bound to here?
And one more confusion when the text says
=bind, is intended to be used in the same way as multiple-value-bind. It takes a list of parameters, an expression, and a body of code: the parameters are bound to the values returned by the expression, and the code body is evaluated with those bindings.
I cannot see the binding directly from the macro definition of =bind which looks like
(defmacro =bind (parms expr &body body)
`(let ((*cont* #'(lambda ,parms ,#body))) ,expr))
Does the binding happens only when =values comes in later?
The macro sets the continuation, *cont*, to be a lambda which takes all of your variables as arguments, and then evaluates the expression expr. The expression is expected to call the continuation with its final value, which can be done indirectly by calling the =values function, or directly with funcall. Unlike Scheme, where the continuation is implicitly called with the return value of any expression, you must explicitly write your code in continuation-passing style by calling *cont* or using =values instead of returning from any function.
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)
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.