I have the following happening in the REPL:
mathematics.core> (let [zebra 1] (resolve 'zebra))
nil
mathematics.core> (def zebra 1)
#'mathematics.core/zebra
mathematics.core> (let [zebra 2] (when (resolve 'zebra) (eval 'zebra)))
1
Basically, I would like to dynamically bind values to variables using something like a let
form, and have functions inside that form be able to access the value the variable is bound to.
mathematics.core> (def ^:dynamic zebra 1)
#'mathematics.core/zebra
mathematics.core> (binding [zebra 2] (when (resolve 'zebra) (eval 'zebra)))
2
binding
seems to do the trick I want, but AFAIK it requires a variable to be defined with the :dynamic
metadata first. I want to be able to use variables that have never been defined before on the fly, and have expressions in the form be able to access that variable as if it were actually defined.
To illustrate, I want something like this:
mathematics.core> (let-dynamic [undefined-variable 1]
(when (resolve 'undefined-variable) (eval 'unresolved-variable)))
1
Is there an easy way to do this? Or a way to accomplish this using macros?
This isn't going to work particularly well. If the symbol isn't defined, then the Clojure compiler can't compile any code that uses it. You might be able to get some kind of hack working with macros that call def lazily when needed, but it would be some pretty nasty code.....
I would suggest just using binding, and define your vars in advance. You should be able to write your code in the way that this works.
I think it's a bad idea to define variables "on the fly". I don't think you should ever really need this - if you are using the variable in the code, surely it is easy enough just to do a (def ^:dynamic ...)
beforehand for each variable that you use?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With