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.

Drew
  • 75,699
  • 9
  • 109
  • 225
buhtz
  • 679
  • 4
  • 22
  • 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 '21 at 13:34
  • You can use `let` to rebind dynamic variables too. Just do `(let ((gc-cons-threshhold 9999999)) …)` – db48x Oct 15 '21 at 14:49
  • But I do not want 300 lines where the `...` are. – buhtz Oct 15 '21 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 '21 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 '21 at 01:57

1 Answers1

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.

db48x
  • 15,741
  • 1
  • 19
  • 23
  • 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 '21 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 '21 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 '21 at 17:33