28

It means that when there is more than one binding the variables are bound sequentially, so that each can depend on the values bound to those that are bound before it, i.e., those that come before it in the let* bindings. For let (no asterisk), none of the bindings can be assumed to occur before any of the others (the variables could, in principle, be bound ...


22

Here is my answer to the identical question, appropriately edited: The Bad foo is self-modifying code. This is extremely dangerous. While the variable lst disappears at the end of the let form, its initial value persists in the function object, and that is the value you are modifying. Remember that in Lisp a function is a first class object, which can be ...


17

Couldn't you use (cl-)letf while referencing the original function yourself? Something like this: ;; Original function (defun my-fun (arg) (message "my-fun (%s)" arg)) ;; Standard call (my-fun "arg") ;; => my-fun (arg) ;; Temporary overriding (more or less like an around advice) (let ((orig-fun (symbol-function 'my-fun))) (letf (((symbol-function '...


13

The documentation for let says: Each element of VARLIST is a symbol (which is bound to nil) or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). The let (var) variant matches the first line — var is a symbol, bound to nil. The let ((var nil)) variant matches the second line — (var nil) where var is the symbol and the initial value is ...


13

@amitp provided the answer. They do have the same behavior. However, IMO they can indicate something slightly different to a human reader of the code -- at least according to an informal convention. That is, they can convey a different connotation. I use (let (foo) ...) only when the initial value is intentionally set in the let body, e.g., in a ...


10

Is it possible to automatically verify that a piece of lisp code does not create any new global variables? Turn on lexical-binding: ;;; foo.el --- just frobnicating some foo -*- lexical-binding: t -*- (setq foo-bar nil) (defun foo-bar () (let (x) (setq y nil))) ;;; foo.el ends here and then the byte-compiler will do the work for you: emacs -Q -...


9

Definitions This topic confuses me sometimes, so let's start with some definitions, namely those of let: let is a special form in ‘C source code’. (let VARLIST BODY...) Bind variables according to VARLIST then eval BODY. The value of the last form in BODY is returned. Each element of VARLIST is a symbol (which is bound to nil) or a list (SYMBOL VALUEFORM)...


8

Common Lisp has a special facility - multiple values, and Emacs Lisp compatibility library emulates them using lists. Thus you can do (defun test-fun () (let ((a 1) (b 2)) (cl-values a b))) (cl-multiple-value-bind (a b) (test-fun) ...) (load cl-lib and use the cl- prefix for all CL functionality in EL). NB: if you look at the SO answer linked ...


7

let* is like a recursive let meaning: (let* ((var1 VAL1) (var2 VAL2)) ...) is like (let ((var1 VAL1)) (let ((var2 VAL2)) ...)) Thereby the usage of capital letters for VAL1 and VAL2 indicates that those can also be expressions. The recursive let-binding has consequences if VAL2 depends actually on var1. The effect is already described in ...


7

You are looking to create a local variable, which can be done with a let-binding. Here's an example: (defun myfun-create-file () "Doc-string." (interactive) (let ((stamp (format-time-string "%Y-%m-%d--%H-%M-%S"))) (find-file-other-frame (concat "C:/Users/me/notes/" stamp ".txt")) (insert (concat "FILE-ID: " stamp ".txt\n"))))


7

I think a reasonable way is to collect all the values into a list and then use a destructuring bind, e.g., pcase-let: (pcase-let ((`(,a ,b ,c) (if t (list 1 2 3) (list 4 5 6)))) (list a b c)) or cl-multiple-value-bind (a bit cleaner than the pcase version since it is specialised to lists, and only allows a single binding clause): (cl-...


6

Here's one way to do it: (let ((a 2)) (pcase 2 ((pred (equal a)) 7))) This snippet uses the fact that (rephrasing (describe-function 'pcase)) a predicate may have the form(FUN ARG1 .. ARGN) in which case it gets called with an N+1'th argument which is the value being matched.


6

Looks like a macro could do that: (defmacro mylet (defs fun body) (list 'let (append defs (funcall fun)) body)) ;; example uses (defun the-dyn-gen () '((a 3) (b 3))) (mylet ((x 1) (y 2)) the-dyn-gen (+ a b x y)) (mylet ((x 1)) the-dyn-gen (+ a b x)) (mylet nil the-dyn-gen (+ a b)) Disclaimer: while this seems to work, macros can be tricky. Note ...


6

Store the original function (obtained with symbol-function) in a local variable, and use funcall to call the function object stored in that variable. Cumbersome, but it mostly works. (defadvice TeX-master-file (around TeX-master-file-indirect-buffer activate compile) "Support indirect buffers." (let ((original-buffer-file-name (symbol-function 'buffer-...


5

setq is doing like expected, the thing here is, that (1 2 3 4) is not a value, so it is not what you think it is. a Place is a location in memory. x and y are Symbols. a Symbol merely points to a place. So x points to (the first cons of) your list. (1 2 3 4) is a List of conses (aka a "chain" of conses). (1 2 3 4) is not a value, but multiple chained ...


5

Since Emacs 26, the underscore (or any variable symbol in general) can be omitted: if-let is a Lisp macro in `subr-x.el'. (if-let SPEC THEN &rest ELSE) Probably introduced at or before Emacs version 25.1. Bind variables according to SPEC and evaluate THEN or ELSE. Evaluate each binding in turn, as in `let*', stopping if a binding value is nil. If ...


4

You can let-bind the keymap variable (presumably tex-file-mode-map) to a new keymap: (let ((tex-file-mode-map (make-sparse-keymap))) ...) Its value before binding it is restored after the let. After binding it, and within the body of the let, assign whatever different bindings you want. Be aware, however, that, any other changes to the map (e.g. by a ...


4

You're tripping over dynamic binding (as opposed to lexical binding). Your current-buffer-name is unbound at the point that your (lambda) function is executed. The let expression only binds it during the function's definition -- there's no closure to capture that value for subsequent evaluation. One simple workaround is to use backquoting like so: `(...


4

Beside relying on the cl-lib compatibility package, the recommended way in Elisp for that is to use pcase: (defun test-fun (let ((a '(a b)) (b '(c d))) `(,a ,b))) (defun other-test-fun () (pcase-let ((`(,a ,b) (test-fun))) (message "a = %s; b = %s" a b))) Beside pcase-let, there's also pcase-dolist, pcase-lambda, and pcase itself.


3

Your example is likely not representative of the actual code you're using, but a good solution might be to create the closure in the macro and return the closure, instead of returning code which may or may not turn into a closure depending on lexical-binding: (defmacro repro () (let* ((kmap-sym (gensym "kmap-"))) `(let ((,kmap-sym (make-sparse-keymap))...


3

It looks like you want to alias a function name within the scope of the my-run-command body, so I'd suggest something more like: (defun my-run-command (command) (cl-letf (((symbol-function 'my-append) #'append)) (apply command))) (my-run-command '(my-append (3 6 8) (4 5))) => (3 6 8 4 5)


3

From the docstring of memory-use-counts, emphasis mine: Return a list of counters that measure how much consing there has been. Each of these counters increments for a certain kind of object. The counters wrap around from the largest positive integer to zero. Garbage collection does not decrease them. So this is the expected output. I couldn't ...


3

The problem is in the let-binding of your defvar form. The let will return the value of its last form. Currently, the last form is define-key, which returns the function symbol which you bound to the keys. Instead, you want to return the map you created: (defvar test-mode-map (let ((map (make-keymap))) (define-key map (kbd "M-S-RET") 'insert-text) ...


3

An alternative to pcase with similar features would also suffice (let ((a 2)) (cond ((eq a 2) 7))) ;; => 7 This isn't a joke - everything that can be done with pcase can also be done with a combination of let and cond. And it think it should be - gratuitous branch-introducing macros aren't helping anyone to either code faster or maintain ...


3

No, the attributes of a face are global. Using face-remapping-alist you can make them buffer local, which won't make you happy. In your case, I would recommend that you define a new face, say my-performed-replacements with your preferred background. When replacing text, you could remap all occurrences of query-replace with my-performed-replacements. It ...


3

[This was going to be a comment to @Drew's answer, but the code will not be rendered correctly.] I gave this a try and wrote a macro using unwind-protect. (defmacro with-keybinding (map key command &rest body) `(let* ((map ,map) (key ,key) (newcommand ,command) (prevbinding (lookup-key map key))) (unwind-protect ...


3

Apologies for not helpfully answering the question posed, but hoping this might help anyway... Instead of something "similar to the first", I'd likely use something that (I think) is simpler than either of them. Your first example macro-"expands" to code that I think is clearer, than either of your examples: (macroexpand '(if-let* ((foo (...


3

Just use let. Write something like this: (let ((foo 323)) …) Where the ellipsis is, place whatever code you wanted to run with foo set to 323. Once that code finishes, foo will go back to having whatever old value it had; there is no need to manually save it and restore it. This is called “lexical scope”. Python actually has lexically–scoped variables as ...


2

There is no idiomatic way to do it, IMO. Do what you like. If you want to be sure to test the condition only once that you are currently retesting, then here is another possibility, where I've used function my-test instead of your vague "x" or "X" (which doesn't seem to actually be referenced in the code you show, which uses t instead): (let* ((test (my-...


2

A quoted list is a constant thus should not be modified, if you modify a constant inside a function, the function will be self-modifying code, for example, ;; Return how many this function is called (defun counter () (cl-incf (car '(0)))) (counter) ;; => 1 (counter) ;; => 2 (counter) ;; => 3 The function returns a different value each time it ...


Only top voted, non community-wiki answers of a minimum length are eligible