1

I'm trying to understand why this doesn't work, and how to make it work:

(defvar test/var-1 nil)
(defvar test/var-2 nil)

(defun make-setter (var-to-set)
  (lambda (val-to-set)
    (setq var-to-set val-to-set)))

(defun do-the-thing ()
  (let ((the-val 5))
    (funcall (make-setter test/var-2) the-val)))

(do-the-thing) ;; After this function is called, I'd expect 
               ;; test/var-2 to have the value 5, but it's nil.

I assume the problem is that the call to setq is setting the value of the symbol var-to-set, overwriting the previous value of test/var-2 with 5. How do I pass in the name of the variable to set and and set the value of that variable?

  • Your first problem is that (make-setter test/var-2) is passing the value of test/var-2, i.e., nil. – npostavs Feb 11 '17 at 1:00
  • 1
    Also see (elisp) Setting Variables – npostavs Feb 11 '17 at 1:02
  • 2
    What @npostavs said. make-setter should be a macro, if you expect VAR-TO-SET not to be evaluated before make-setter gets hold of it. You also have a problem in expecting a relationship between that local variable for the function and the other variable of the same name that is bound by the lambda form. There are really several things wrong with the code. You would do well to read some of the Emacs Lisp Intro manual, (An Introduction to Programming in Emacs Lisp) available by doing C-h i. – Drew Feb 11 '17 at 2:42
  • @drew yes, I am reading it, thanks; I'm asking questions here because I find elisp complex and I haven't gotten my head around everything I've read. I appreciate the suggestion about macros, though. Will dig in to that. – Gastove Feb 11 '17 at 19:32
2

First of all, closures won't work in Emacs Lisp without setting lexical-binding to t for the file. Dynamic scoping (which is used by default) makes it impossible to create closures.

To turn on lexical scoping, put this as the first line of the file with your code:

;;; -*- lexical-binding: t -*-

If you want to set the value of an arbitrary symbol, use set instead of setq, which quotes the name of the symbol you want to set.

When passing a symbol as an argument, make sure you quote it by putting an apostrophe in front of it.

  • This got me where I needed to get, thanks! – Gastove Mar 17 '17 at 18:30

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.