Reputation: 2891
I have a variable "name" which's value is the name of another variable. So for example :
(define name 'a)
(define a 1)
I would then want to do something like this :
(set! ,name 10)
But this gives rise to an error, so I would like that ",name" is replaced by it's value (i.e. 'a). So that the above code sets the value of variable "a" to 10 and that the "name" variable stays unchanged.
I know I can do it like this :
(eval `(set! ,name 10))
But this only works if the variable contained in "name" is a global variable, which is not the case in my program.
Currently I solved the problem by introducing a new namespace but this makes the code a bit ugly, that's why I would avoid using eval (and thus also avoid introducing a new namespace).
If I'm not mistaking me in C++ this would be done by dereferencing a handle (pointer to a pointer).
Upvotes: 3
Views: 241
Reputation: 31147
The reason that (eval `(set! ,name 10))
doesn't work, is that the names of local variables aren't present at runtime. Local variables are stored at the stack, so references and assignment to local variables are compiled to "get the value in the i'th variable (counted from the top of the stack)" and "store this value in the i'th slot at the stack".
Module level variables are however stored in a namespace, so you can use the eval
solution for them.
So what to do with local variables? It would probably be best to use hash table instead, but if you really need it, do something like this:
(define (set-local-variable name val)
(match name
['a (set! a val)]
['b (set! b val)]
...))
where a, b, ... are the local variables. You'll of course need to place the definition in the scope of the local variables in question. This also implies you'll need to define a set-local-variable
for each scope.
This quickly becomes a pain to maintain, so look for an alternative solution - for example one based on hash tables.
Upvotes: 3