1

I have problems to get into Lisp. I assume I miss the correct terms to search for. So I try to "speak in Python".

#!/usr/bin/env python3
foo = 7
backuped_foo = foo

# temporary change the value of foo
foo = 323

# restore the original foo value
foo = backuped_foo

So I would I do this in Emacs Lisp?

EDIT: I am not interested in lexial scoping or other concepts for a solution. I am only interested in an nearly exact technical copy of that python code into Lisp.

This is inspired by another answer:

(setq foo 7)  ;; original value
(setq backuped_foo foo)  ;; remember it for later restore

(setq foo 4373)  ;; temporary value

;; ...
;; do a lot of stuff where a lexical scoope does not help
;; ...


(setq foo backuped_foo)  ;; restore the original value

At the end foo==7 (do not know how to express this in Lisp) so everything is fine. But I am not sure if this is a good and Lisp-like way.

In real I need this to modify a global variable (gc-cons-threshold) while a script (init.el) is running. When the script is finished I need to restore the original value.

5
  • 2
    Your answer will work, but it is not the lisp-like way. The lisp-like way to do it is to use a (let ...) statement as shown in the answer from @db48x
    – Tyler
    Oct 15, 2021 at 13:34
  • You can use let to rebind dynamic variables too. Just do (let ((gc-cons-threshhold 9999999)) …)
    – db48x
    Oct 15, 2021 at 14:49
  • But I do not want 300 lines where the ... are.
    – buhtz
    Oct 15, 2021 at 15:11
  • 2
    @buhtz You can use (let ((gc-cons-threshhold 9999999)) (load "my-init.el")). No need to physically have so many lines there.
    – npostavs
    Oct 15, 2021 at 17:37
  • 1
    Or define a function: (defun my-300-lines-of-stuff () …), and then call it inside the let: (let ((gc-cons-threshhold 9999999)) (my-300-lines-of-stuff)).
    – db48x
    Oct 16, 2021 at 1:57

1 Answer 1

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 well, though perhaps it is not quite as succinct. Consider this code:

foo = 7

def do_something:
  foo = 323
  …

do_something()

When you enter do_something, foo takes on a new value, and that value is restored automatically when do_something returns. In Emacs Lisp, let allows you to do the same thing but without defining a function every time you want to use it.

If you want to learn more about the Emacs Lisp language, I recommend reading the manual that is included with Emacs. The keyboard shortcut C-h i will open the Info viewer. It should open to a list of manuals, unless you have recently viewed a specific manual in which case it opens to whatever you were reading before. In the Info viewer, d will take you back to the index, where you can find the manual for Emacs Lisp. The whole manual is worth reading, but you should specifically take a look at chapter 12 Variables, which covers the topic quite thoroughly. chapter 12.10 Scoping Rules for Variable Bindings goes into the details of both dynamic and lexical scoping for variables.

3
  • 1
    Thank you very much for your valuable answer. But it did not answer my question because I am not interested in a concept but just a word-by-word translation from Python to Lisp.
    – buhtz
    Oct 15, 2021 at 12:02
  • 3
    There is no word by word translation between any two different programming languages, they do things in different ways. You have to learn the idioms of each language. You can carry over ideas but they wont be the same. In this case this answer shows the python local way to do this - which is better python than your original - and this maps to the lisp let way. The setq version is a direct copy of your python but it is not idiomatic python or lisp - or any language design since 1970 - use local variables not globals
    – mmmmmm
    Oct 15, 2021 at 12:40
  • 1
    It's worth mentioning that the let binding will use dynamic scope if the variable has been declared with defvar or similar.
    – npostavs
    Oct 15, 2021 at 17:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.