0

Is it possible to set a symbol that is the value of target symbol within the let bind form? because I am not setting a target symbol, I am not sure how to use let.

I am doing this because I am passing in a string that represents a library's name to generate a function for the library. look at the following link to see how I am using it https://github.com/natask/sexp-string/blob/6b748c133da51a129a465a426ae43b06c3a1331d/sexp-string.el#L189.

starting point, The following is a valid let form

(setq boolean 'dynamic-value)
(print boolean) ;; prints 'dynamic-value
(let ((boolean 'lexical-value))
   (print boolean)) ;; prints 'lexical-value

I am looking to modify lexically the variable boolean from a variable boolean-variable that contains the symbol boolean. boolean-variable is like a pointer to the pointer boolean.

(setq boolean 'first-value)
(setq boolean-variable 'boolean)
(print (symbol-value boolean-variable)) ;; prints 'first-value
(set  boolean-variable 'second-value)
(print boolean) ;; prints 'second-value

what I have,

(setq boolean 'dynamic-value)
(setq boolean-variable (intern-soft "boolean"))
(print boolean-variable) ;; prints 'boolean
(print (symbol-value boolean-variable)) ;; prints 'dynamic-value
(let ((old-boolean-variable (symbol-value boolean-variable)))
          (set boolean-variable 'lexical-value)
          ;; use boolean-variable in a function
          (print (symbol-value boolean-variable)) ;; prints 'lexical-value
          ;; set the value of variable back to previous value
          (set boolean-variable old-boolean-variable))
(print (symbol-value boolean-variable))  ;; prints 'dynamic-value

what I am looking for ,

(setq boolean 'dynamic-value)
(setq boolean-variable (intern-soft "boolean"))
(print boolean-variable) ;; prints 'boolean
(print (symbol-value boolean-variable)) ;; prints 'dynamic-value
(let (((symbol-content boolean-variable) 'lexical-value))) ;; creates a lexical binding to symbol 'boolean
    (print (access-symbol-lexically boolean-variable)) ;; prints 'lexical-value
)
(print (symbol-value boolean-variable)) ;; prints 'dynamic-value

I am not using the variable boolean directly but through a symbol because I am passing in a string something like the following.

(setq boolean-1 'dynamic-value)
(setq boolean-2 'dynamic-value)
(defun my-fun (library)
(setq boolean-variable1 (intern-soft (concat library "-1")))
(setq boolean-variable2 (intern-soft (concat library "-2")))
;;utilize variables
)
(my-fun "boolean")
7
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Aug 31, 2021 at 2:25
  • 1
    (1) The question isn't clear to me at all - but that might just be me. I have no idea what you're trying to do or asking. (2) symbol-value is explicitly for dynamically scoped variables. See C-h f symbol-value and (elisp) Accessing Variables.
    – Drew
    Aug 31, 2021 at 2:32
  • 2
    Your example let form is strange/confusing. The whole "save the current value, do a thing, restore the original value" process is robustly taken care of by let -- you don't need to manually save and restore the value; it will be restored once the let-binding ends. Following (let ((foo newvalue)) do-a-thing) the symbol foo will have its original value again.
    – phils
    Aug 31, 2021 at 5:06
  • @drew, I have added more context. In short, lexically utilize a variable behind a variable as supposed to lexically utilizing a variable. Sep 1, 2021 at 21:01
  • I don't see any edit with additional context. The question is still not clear to me.
    – Drew
    Sep 1, 2021 at 23:05

2 Answers 2

0

To my knowledge, if you have lexical-binding enabled in your library, then it cannot treat a given name as both dynamic and lexical. If you have declared a variable as dynamic by using defvar, then it will not be treated as lexically-bound. You must pick one or the other. This shouldn't be a problem because, by definition, all of the code which can access a lexically-bound variable is right there in that same block of code (within the scope of the lexical binding), where you can edit it -- so there's absolutely no reason to be using the same name as a dynamic variable.

Alternatively (but again, I don't see why you might need this) you can utilise the fake lexical binding macro lexical-let from the cl library, which was typically used to imitate lexical binding back when Emacs only supported dynamic binding.


I am looking to modify lexically the variable boolean from a variable boolean-variable that contains the symbol boolean. boolean-variable is like a pointer to the pointer boolean.

No, if you are using lexical-binding then this is not possible at all. There's no way of taking a symbol name and using it to find a lexical variable of that name, because the lexical variable isn't associated with the symbol at all.

C-hig (elisp)Lexical Binding explains:

Note that unlike dynamic variables which are tied to the symbol object itself, the relationship between lexical variables and symbols is only present in the interpreter (or compiler). Therefore, functions which take a symbol argument (like ‘symbol-value’, ‘boundp’, and ‘set’) can only retrieve or modify a variable’s dynamic binding (i.e., the contents of its symbol’s value cell).

Within the scope of a lexical-binding the only code which can access a given lexical variable is the code which directly references the variable name.

2
  • do you think there is a better way to use variables of a symbol as symbols themselves than creating a backup and reverting as above? Sep 2, 2021 at 5:47
  • I'm still not entirely sure what you're doing, but one option would be to write a lisp macro which generates let bindings for the actual variable names (i.e. the ones generated from the strings) and evaluates the body code within that.
    – phils
    Sep 2, 2021 at 5:58
0

@phils comment on his answer lead me to think of the following.

(setq boolean 'dynamic-value)
(setq boolean-variable (intern-soft "boolean"))
(print boolean-variable) ;; prints 'boolean
(print (symbol-value boolean-variable)) ;; prints 'dynamic-value
(eval `(let ((,boolean-variable 'lexical-value)) ;; creates a lexical binding
    (print ,boolean-variable) ;; prints 'lexical-value
    (print boolean) ;;prints 'lexical-value
))
(print (symbol-value boolean-variable)) ;; prints 'dynamic-value

strangely, I had to pass environment variables to eval in my case. I had thought eval captures environment variables automatically. https://github.com/natask/sexp-string/blob/9fbacdf620d9077b60270c63eaa6267be75fd855/sexp-string.el#L200

                    (eval
                     `(let ((,boolean-variable (or boolean ,boolean-variable)))
                     (pcase parsed-sexp
                        (`(,_) (->> `,(backquote ,(car parsed-sexp))
                                    backquote
                                    eval
                                    sexp-string-collapse-list))
                        (_ nil))) (list (cons 'boolean boolean) (cons 'parsed-sexp parsed-sexp))))))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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