The scoping in Lisp is new to me and I think I've got it figured out, but the one area that confuses me a bit is how to mutate a global variable in a function without mentioning it specifically:
(defun empty-it (var)
"Remove everything from var."
(setf var nil))
Now, if I have *some-var* and call (empty-it *some-var*) it doesn't work, because the variables retains its contents from the scope prior to entering the function. Obviously, this works:
(defun empty-it-explicit ()
"Remove everything *some-var*."
(setf *some-var* nil))
Is it possible to have a general function that will clear the permanent contents of a stored variable, and have it work on any variable you pass to it? In other words, must you always explicitly mention a variable's name if you want it changed permanently?
(defun set-somevar-with-function (fn)
"Pass *some-var* into a function and set it to the results."
(setf *some-var* (funcall fn *some-var*)))
CL> (set-somevar-with-function #'empty-it)
Is this the correct Lisp idiom? If you had multiple vars you wanted to permanently mutate, would you have to write a separate function for each variable, each explicitly mentioning a different variable?
Basics
The scoping in Lisp is new to me and I think I've got it figured out,
but the one area that confuses me a bit is how to mutate a global
variable in a function without mentioning it specifically.
The scoping, aside from the availability of dynamically scoped variables, isn't really much different than what's available in other languages. E.g., in C, if you do something like:
void frob( int x ) {
x = 0;
}
int bar() {
int x = 3;
frob( x );
printf( "%d", x );
}
you'd expect to see 3 printed, not 0, because the x in frob and the x in bar are different variables. Modifying one doesn't change the value of the other. Now, in C you can take the address of a variable, and modify that variable through the pointer. You don't get pointers in Common Lisp, so you need something else if you want a layer of indirection. For lexical variables, you need to use closures for that purpose. For global variables (which are dynamically scoped), though, you can use the symbol that names the variable.
Direct modification of a variable (lexical or dynamic)
You can refer to global variables in the same way that you refer to any other variables in Common Lisp, by simply writing their name. You can modify them with setq or setf. E.g., you can do
(setq *x* 'new-value-of-x)
(setf *x* 'newer-value-of-x)
Indirect modification of a variable (dynamic only)
You can also take the symbol *x*, and use set or (setf symbol-value) to change the value:
(setf (symbol-value '*x*) 'newest-value-of-x)
(set '*x* 'newester-value-of-x)
Those cases give you some flexibility, because they mean that you can take the symbol as an argument, so you could do:
(defun set-somevar-with-function (var-name)
(setf (symbol-value var-name)
(funcall fn (symbol-value var-name))))
Understanding variable bindings (lexical and dynamic)
(Note: This is really just a rehashing of the C example above.) I think you understand why this bit of code that you posted doesn't work, but I want to mention a bit about it, just in case anyone with less experience comes across this question.
(defun empty-it (var)
"Remove everything from var."
(setf var nil))
Now, if I have *some-var* and call (empty-it *some-var*) it doesn't
work, because the variables retains its contents from the scope prior
to entering the function.
There's no unusual sense in which any variable is retaining or not retaining its value from one scope or another here. The evaluation model says that to evaluate (empty-it *some-var*), the system finds the function binding of empty-it and takes the value of *some-var*, let's call it x, and calls the function value of empty-it with the x. In doing that call, the variable var is bound to the value x. The call (setf var nil) modifies the variable var, and var has nothing to do with the variable *some-var*, except that for a while they happened to have the same value. Nothing here essentially depends on *some-var* being a global or dynamic variable, or on *some-var* and var having different names. You'd get the same results with another variable of the same name, e.g.:
(defun empty-it (var)
(setf var nil))
(let ((var 'value))
(empty-it var)
var)
;=> 'value
You'd even get the same if the parameter of empty-it were called *some-var*:
(defun empty-it (*some-var*)
(setf *some-var* nil))
(progn
(setf *some-var* 'value)
(empty-it *some-var*)
*some-var*)
;=> 'value
Beware of dynamic rebindings
Now, this will all work just fine if you're only modifying these variables, and you're never making new bindings for them. When you define a variable with defparameter or defvar, you're also globally proclaiming it special, i.e., dynamically scoped. The modifications done with set or setf are done to the most recent in scope binding of the variable. (When you modify a lexical variable, you're updating the innermost lexically enclosing binding.) This leads to results like the following:
(defparameter *x* 'first-value) ; AA
(defun call-and-modify (function name)
(setf (symbol-value name)
(funcall function
(symbol-value name))))
(progn
(let ((*x* 'second-value)) ; BB
(let ((*x* 'third-value)) ; CC
(print *x*) ; third-value (binding CC)
(call-and-modify (constantly 'fourth-value) '*x*)
(print *x*)) ; fourth-value (binding CC)
(print *x*)) ; second-value (binding BB)
(print *x*)) ; first-value (binding AA)
Symbols can be unbound with makunbound. Then the symbol is not just empty but gone. The danger, as always with mutation, is shared structure. hyperspec:makunbound
The symbol-function value of a symbol can be unbound with fmakunbound. hyperspec:fmakunbound
? (setf (symbol-value 'b) 42)
42
? (setf (symbol-function 'b)(lambda (x)(+ x 1)))
#<Anonymous Function #x210057DB6F>
? b
42
? (b 4)
5
? (fmakunbound 'b)
B
? b
42
? (b 4)
> Error: Undefined function B called with arguments (4) .
> ...[snipped]
> :pop
? b
42
? (makunbound 'b)
B
? b
> Error: Unbound variable: B
> ...[snipped]
> :pop
?
If you're looking for idiomatic lisp, I think (though I'm far from expert at lisp) the thing you want is to simply not have your function do the emptying. It can supply an empty value, just let that be it. So instead of having:
(defun empty-it (var)
(setf var nil))
; and then somewhere down the line calling:
(empty-it var)
You might do:
(defun empty ()
nil)
; and then somewhere down the line, call:
(setf var (empty))
Common-lisp is not limited to being (and maybe could be said simply not to be) a functional language, but for this, you'll want to take a (more) functional approach – meaning that your function may take a value, but it doesn't modify variables, it simply returns another value.
Of course, if your goal is to have the semantic expression of "make this thing empty", you could use a macro:
(defmacro empty-it (var)
`(setf ,var nil))
; and then, down the road, you can indeed call:
(empty-it var)
This would also be reasonably idiomatic.
Related
Coming from a C++ background, I'm trying to figure out how arguments are passed into methods in Elisp. While I acknowledge that maybe the wording could be different, I'm wondering if it is closer to the C++ idea of passing by reference or passing by value? If I alter the parameter in the method itself, will it alter the parameter that was passed in in the function call?
All Lisps (Emacs Lisp, Common Lisp) pass parameters by value, always:
(defparameter x 42) ; defconst in Emacs Lisp
(defun test (x)
(setq x 10))
(test x)
==> 10
x
==> 42
Note, however, that some values are actually pointers (or, rather, objects with components), so a function can modify their content by side effects:
(defparameter x (list 1 2))
(defun test (x)
(setf (first x) 42
(second x) 24
x 17))
(test x)
==> 17
x
==> (42 24)
PS1. Cf. When to use ' (or quote) in Lisp? -- "quoted arguments" are evaluated too: the evaluation strips the quote.
PS2. Cf. add-to-list - it accepts a symbol (variable name) and modifies its value. This only works for global dynamic variables, not for lexical variables. Not a very good idea.
Actually, in Emacs Lisp, there is no such thing like passing a argument by value or by reference, not to mention pointer. But all arguments passed to function will be evaluated in advance except those have a ' prefix. Always remember When you set a variable, you always just create symbol with a value.[1]
So if you want to modify a variable's value in a function, all you need to do is modifying the value of that variable's symbol in that function.
Check my code bellow.
(defvar my-val 1)
(defun my-func-value (val)
(setq val 2))
(defun my-func-symbol (sym)
;; NOTE! using set instead of setq,
;; casue we want symbol "my-val" be evaluated from "sym" here
(set sym 2))
(my-func-value my-val) ; evaluate my-val before passed into function
(message "my-val: %s" my-val) ; my-val: 1
(my-func-symbol 'my-val) ; pass my-val symbol directly into function
(message "my-val: %s" my-val) ; my-val: 2
Note! If the variable is a lexically-bound variable[2], it's still true that you can modified the symbol's value but not the value in the lexical environment.
Here is the code:
(let ((my-lexical-var 1))
(my-func-symbol 'my-lexical-var)
;; evaluate from lexical environment
(message "my-lexical-var: %s" my-lexical-var) ; my-lexical-var: 1
;; evaluate from the symbol
(message "symbol my-lexical-var: %s" (symbol-value 'my-lexical-var))
; symbol my-lexical-var: 2
I'm doing a tutorial on emacs lisp, and it's talking about the let function.
;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello local-name)
(other-window 1))
I don't understand the role of the double parentheses after let in the first line. What are they doing that a single set wouldn't do? Running that section without them, I get an error: Wrong type argument: listp, "you".
You can introduce multiple variables there. The outer parentheses delimit the list of bindings, the inner the individual binding form.
(let ((foo "one")
(bar "two"))
(frobnicate foo bar))
There are not "double parens".
Presumably, you are thinking of (let ((foo...)...)), and you mean the (( that come after let? If so, consider this:
(let (a b c) (setq a 42)...)
IOW, let declares local variables. It may also bind them. In the previous sexp, it declares a, b, and c, but it doesn't bind any of them, leaving it to the let body to give them values.
An example that declares two variables but binds only one of them (a):
(let ((a 42) b) ... (setq b ...) ...)
According to gnu.org, it looks like you can construct and initialize multiple variables with one let statement, so the double parenthesis is there to allow the separation between the variables.
If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:
(let ((variable value)
(variable value)
…)
body…)
The let special form takes a list of bindings: (let (<binding-form> ...) <body>).
The binding form is one of <symbol> (denoting a variable bound to the value nil) or a list (<symbol> <value>) (where value is computed when the let is entered).
The difference between let and let* is how the "value" bits are executed. For plain let, they're executed before any of the values are bound:
(let ((a 17)
(b 42))
(let ((a b) ; Inner LET
(b a))
(list a b)))
Whereas let* executes the binding forms one after another. Both have their places, but you can get by with only using let since (let* (<form1> <form2>...) is equivalent to (let (<form1>) (let (<form2>) ...))
I am not sure what is going on here, a macro example in the text.
Basically, not comfortable with how to use get-setf-method, a built-in macro (maybe function?).
To be specific, how about the case that some of the return values of get-setf-method are nil?
e.g.
(get-setf-method 'x)
NIL ;
NIL ;
(#:NEW-3069) ;
(SETQ X #:NEW-3069) ;
X
And why this example code set the fifth return value to the second return value first, for initialization?
Finally how it can handle the order of setting the variables in an expression, such as (aref ar (incf i)
(get-setf-method '(aref ar (incf i)))
(#:G3070 #:G3071) ;
(AR (INCF I)) ;
(#:G3072) ;
(SYSTEM::STORE #:G3070 #:G3071 #:G3072) ;
(AREF #:G3070 #:G3071)
Here is the definition of the macro :
(defmacro sortf (op &rest places)
(let* ((meths (mapcar #'(lambda (p)
(multiple-value-list
(get-setf-method p)))
places))
(temps (apply #'append (mapcar #'third meths))))
`(let* ,(mapcar #'list
(mapcan #'(lambda (m)
(append (first m)
(third m)))
meths)
(mapcan #'(lambda (m)
(append (second m)
(list (fifth m))))
meths))
,#(mapcon #'(lambda (rest)
(mapcar
#'(lambda (arg)
`(unless (,op ,(car rest) ,arg)
(rotatef ,(car rest) ,arg)))
(cdr rest)))
temps)
,#(mapcar #'fourth meths))))
That's actually some older code. get-setf-method was actually replaced by get-setf-expansion as described in Issue SETF-METHOD-VS-SETF-METHOD Writeup. So what you should be interested in these days is get-setf-expansion. The values that it returns are the pieces of code that you need to safely store a value in a location. This is very important because it's very easy to write modyfing macros incorrectly.
As to why some of the values can be nil, one of the examples in the documentation for get-setf-expansion actually shows how some of the values can be nil:
(get-setf-expansion 'x)
;=> NIL, NIL, (#:G0001), (SETQ X #:G0001), X
But what are those values? For that we need to look at the syntax of the documentation:
Syntax:
get-setf-expansion place &optional environment
⇒ vars, vals, store-vars, writer-form, reader-form
Arguments and Values:
place—a place.
environment—an environment object.
vars, vals, store-vars, writer-form, reader-form—a setf expansion.
Those five return values are described in 5.1.1.2 Setf Expansions:
List of temporary variables a list of symbols naming temporary variables to be bound sequentially, as if by let*, to values resulting
from value forms.
List of value forms a list of forms (typically, subforms of the place) which when evaluated yield the values to which the
corresponding temporary variables should be bound.
List of store variables a list of symbols naming temporary store variables which are to hold the new values that will be assigned to
the place.
Storing form a form which can reference both the temporary and the store variables, and which changes the value of the place and
guarantees to return as its values the values of the store variables,
which are the correct values for setf to return.
Accessing form a form which can reference the temporary variables, and which returns the value of the place.
So what do those values in the example mean?
(get-setf-expansion 'x)
;⇒ NIL, NIL, (#:G0001), (SETQ X #:G0001), X
To write to variable x, we don't need any temporary storage, and since there are no temporary values, we don't need any forms to produce values for them. We can notice here that the first and second values are always lists, and they should always have the same length. The third value is a list of store variables. This is a list, because we can actually use setf to modify multiple values, but in this case there's just one. The variables here are where the macro should actually store the new values for the place. Then, it's the writer-form (setq x #:g0001) that will actually take care of putting the value in the place. x, of course, is a simple way of reading the value.
As a more complex example, have a look at this transcript from SBCL:
CL-USER> (defstruct person
person-name)
;⇒ PERSON
CL-USER> (get-setf-expansion '(char (person-name (first (second list-of-list-of-persons))) 3))
; (#:TMP965)
; ((PERSON-NAME (FIRST (SECOND LIST-OF-LIST-OF-PERSONS))))
; (#:NEW964)
; (SB-KERNEL:%CHARSET #:TMP965 3 #:NEW964)
; (CHAR #:TMP965 3)
This means that if we wanted to change the fourth character of the name of the first person in the second list of persons in a list of lists of persons, we could do it with:
(let* ((temp965 (person-name (first (second list-of-list-of-persons))))
(old-char (char tmp965 3))) ; optional
(setq new964 <compute-new-value>)
(sb-kernel:%charset tmp965 3 new964))
We can compute the new value however we want (just fill in for <compute-new-value>), and we can even reference the old value if we want to (by including the optional line). All we need to do is set new964 to the new value, and then execute the writer-form that was given to us.
There are more examples of get-setf-expansion on Stack Overflow:
what is to append as push is to cons, in Lisp?
Writing a destructive macro or function like incf?
Writing a ++ macro in Common Lisp
How could I implement the push macro?
I am a novice in Lisp, learning slowly at spare time... Months ago, I was puzzled by the error report from a Lisp REPL that the following expression does not work:
((if (> 2 1) + -) 1 2)
By looking around then I knew that Lisp is not Scheme...in Lisp, I need to do either:
(funcall (if (> 2 1) '+ '-) 2 1), or
(funcall (if (> 2 1) #'+ #'-) 2 1)
I also took a glimpse of introductary material about lisp-1 and lisp-2, although I was not able to absort the whole stuff there...in any case, I knew that quote prevents evaluation, as an exception to the evaluation rule.
Recently I am reading something about reduce...and then as an exercise, I wanted to write my own version of reduce. Although I managed to get it work (at least it seems working), I realized that I still cannot exactly explain why, in the body of defun, that some places funcall is needed, and at some places not.
The following is myreduce in elisp:
(defun myreduce (fn v lst)
(cond ((null lst) v)
((atom lst) (funcall fn v lst))
(t (funcall fn (car lst) (myreduce fn v (cdr lst))))))
(myreduce '+ 0 '(1 2 3 4))
My questions are about the 3rd and 4th lines:
The 3rd line: why I need funcall? why not just (fn v lst)? My "argument" is that in (fn v lst), fn is the first element in the list, so lisp may be able to use this position information to treat it as a function...but it's not. So certainly I missed something here.
The 4th line in the recursive call of myreduce: what kind of fn be passed to the recursive call to myreduce? '+ or +, or something else?
I guess there should be something very fundamental I am not aware of...I wanted to know, when I call myreduce as shown in the 6th/last line, what is exactly happening afterwards (at least on how the '+ is passed around), and is there a way to trace that in any REPL environment?
Thanks a lot,
/bruin
Common Lisp is a LISP-2 and has two namespaces. One for functions and one for variables. Arguments are bound in the variable namespace so fn does not exist in the function namespace.
(fn arg) ; call what fn is in the function namespace
(funcall fn ...) ; call a function referenced as a variable
'+ is a symbol and funcall and apply will look it up in the global function namespace when it sees it's a symbol instead of a function object. #'+ is an abbreviation for (function +) which resolves the function from the local function namespace. With lots of calls #'+ is faster than '+ since '+ needs a lookup. Both symbol and a function can be passed as fn to myreduce and whatever was passed is the same that gets passed in line 4.
(myreduce '+ 0 '(1 2 3 4)) ; here funcall might lookup what '+ is every time (CLISP does it while SBLC caches it)
(myreduce #'+ 0 '(1 2 3 4)); here funcall will be given a function object looked up in the first call in all consecutive calls
Now if you pass '+ it will be evaluated to + and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to + too.
For #'+ it evaluates to the function and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to the function object fn was bound to in the variable namespace.
Common Lisp has construct to add to the function namespace. Eg.
(flet ((double (x) (+ x x))) ; make double in the function namespace
(double 10)) ; ==> 20
But you could have written it and used it on the variable namespace:
(let ((double #'(lambda (x) (+ x x)))) ; make double in the variable namespace
(funcall double 10))
Common Lisp has two (actually more than two) namespaces: one for variables and one for functions. This means that one name can mean different things depending on the context: it can be a variable and it can be a function name.
(let ((foo 42)) ; a variable FOO
(flet ((foo (n) (+ n 107))) ; a function FOO
(foo foo))) ; calling function FOO with the value of the variable FOO
Some examples how variables are defined:
(defun foo (n) ...) ; n is a variable
(let ((n 3)) ...) ; n is a variable
(defparameter *n* 41) ; *n* is a variable
So whenever a variable is defined and used, the name is in the variable namespace.
Functions are defined:
(defun foo (n) ...) ; FOO is a function
(flet ((foo (n) ...)) ...) ; FOO is a function
So whenever a function is defined and used, the name is in the function namespace.
Since the function itself is an object, you can have function being a variable value. If you want to call such a value, then you need to use FUNCALL or APPLY.
(let ((plus (function plus)))
(funcall plus 10 11))
Now why are things like they are? ;-)
two namespaces allow us to use names as variables which are already functions.
Example: in a Lisp-1 I can't write:
(defun list-me (list) (list list))
In Common Lisp there is no conflict for above code.
a separate function namespace makes compiled code a bit simpler:
In a call (foo 42) the name FOO can only be undefined or it is a function. Another alternative does not exist. So at runtime we never have to check the function value of FOO for actually being a function object. If FOO has a function value, then it must be a function object. The reason for that: it is not possible in Common Lisp to define a function with something other than a function.
In Scheme you can write:
(let ((list 42))
(list 1 2 3 list))
Above needs to be checked at some point and will result in an error, since LIST is 42, which is not a function.
In Common Lisp above code defines only a variable LIST, but the function LIST is still available.
I'm trying to create a function on the fly that would return one constant value.
In JavaScript and other modern imperative languages I would use closures:
function id(a) {
return function() {return a;};
}
but Emacs lisp doesn't support those.
I can create mix of identity function and partial function application but it's not supported either.
So how do I do that?
Found another solution with lexical-let
(defun foo (n)
(lexical-let ((n n)) #'(lambda() n)))
(funcall (foo 10)) ;; => 10
Real (Not Fake) Closures in Emacs 24.
Although Emacs 24 has lexical scooping when the variable lexical-binding has value t, the defun special form doesn’t work properly in lexically bound contexts (at least not in Emacs 24.2.1.) This makes it difficult, but not impossible, to define real (not fake) closures. For example:
(let ((counter 0))
(defun counting ()
(setq counter (1+ counter))))
will not work as expected because the symbol counter in the defun will be bound to the global variable of that name, if there is one, and not the lexical variable define in the let. When the function counting is called, if the global variable doesn’t, exist then it will obviously fail. Hoever if there is such a global variable it be updated, which is probably not what was intended and could be a hard to trace bug since the function might appear to be working properly.
The byte compiler does give a warning if you use defun in this way and presumably the issue will be addressed in some future version of Emacs, but until then the following macro can be used:
(defmacro defun** (name args &rest body)
"Define NAME as a function in a lexically bound context.
Like normal `defun', except that it works correctly in lexically
bound contexts.
\(fn NAME ARGLIST [DOCSTRING] BODY...)"
(let ((bound-as-var (boundp `,name)))
(when (fboundp `,name)
(message "Redefining function/macro: %s" `,name))
(append
`(progn
(defvar ,name nil)
(fset (quote ,name) (lambda (,#args) ,#body)))
(if bound-as-var
'nil
`((makunbound `,name))))))
If you define counting as follows:
(let ((counter 0))
(defun** counting ()
(setq counter (1+ counter))))
it will work as expected and update the lexically bound variable count every time it is invoked, while returning the new value.
CAVEAT: The macro will not work properly if you try to defun** a function with the same name as one of the lexically bound variables. I.e if you do something like:
(let ((dont-do-this 10))
(defun** dont-do-this ()
.........
.........))
I can’t imagine anyone actually doing that but it was worth a mention.
Note: I have named the macro defun** so that it doesn’t clash with the macro defun* in the cl package, however it doesn’t depend in any way on that package.
Stupid idea: how about:
(defun foo (x)
`(lambda () ,x))
(funcall (foo 10)) ;; => 10
Emacs lisp only has dynamic scoping. There's a lexical-let macro that approximates lexical scoping through a rather terrible hack.
Emacs 24 has lexical binding.
http://www.emacswiki.org/emacs/LexicalBinding
;; -*- lexical-binding:t -*-
(defun create-counter ()
(let ((c 0))
(lambda ()
(setq c (+ c 1))
c)))
(setq counter (create-counter))
(funcall counter) ; => 1
(funcall counter) ; => 2
(funcall counter) ; => 3 ...
http://www.emacswiki.org/emacs/FakeClosures