get value from dynamic key in clojure map

clojure, dictionary

Solution

`(:(environment) names)` is not a valid form. Unless `environment` is a function of no arguments, you will get an error from wrapping it in parens. usage of `:` to create keywords is done at read time, before `(environment)` is evaluated, so you do not see the previous error, and the reader attempts to resolve `:` on its own, which is not a valid input to the reader.

`(keyword(":" env) names)` attempts to call the string ":" as if it were a function. It is not one. Also the spacing leads me to beleive that you expect `keyword(arg)` to work as it would in an Algol family language. It will not. The proper usage is `(keyword arg)`.

here is what works, with a few equivalent syntaxes avaliable for convenience (they all do the same thing):

user> (def names {:production "prayag" :staging    "upd"})
#'user/names
user> (def environment "staging")
#'user/environment
user> (names (keyword environment))
"upd"
user> ((keyword environment) names)
"upd"
user> (get names (keyword environment))
"upd"

Problem

I have a clojure map ``` + 69 (def names {:production "prayag" + 70 :staging "upd"}) ``` I need to get a value from a key variable `environment` that would be dynamic. Something like below throws Exception, ``` + 72 (defn get-name [environment] + 73 (let [ + 74 name (:(environment) names)] + 75 println name + 76 )) ``` Stacktrace ``` Caused by: java.lang.RuntimeException: Invalid token: : at clojure.lang.Util.runtimeException(Util.java:219) at clojure.lang.LispReader.interpretToken(LispReader.java:326) at clojure.lang.LispReader.read(LispReader.java:211) at clojure.lang.LispReader.readDelimitedList(LispReader.java:1157) at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982) at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148) at clojure.lang.LispReader$VectorReader.invoke(LispReader.java:1083) at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148) at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982) at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148) at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982) at clojure.lang.LispReader.read(LispReader.java:185) at clojure.lang.Compiler.load(Compiler.java:7060) ... 55 more ``` While following code, ``` + 72 (defn get-name [env] + 73 (let [ + 74 name (keyword(":" env) names)] + 75 println name + 76 )) ``` gives ``` Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn at nepleaks_engine.util.utility$fn__3885.invoke(utility.clj:74) at clojure.lang.AFn.applyToHelper(AFn.java:159) at clojure.lang.AFn.applyTo(AFn.java:151) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3458) ... 58 more ``` And ``` + 72 (defn get-name [env] + 73 (let [ + 74 name (.get names env)] + 75 println name + 76 )) ``` gives ``` java.lang.NullPointerException at nepleaks_engine.util.utility$util.invoke(utility.clj:81) at nepleaks_engine.core$_main.invoke(core.clj:14) at clojure.lang.Var.invoke(Var.java:411) at user$eval5$fn__7.invoke(form-init336568295343421746.clj:1) at user$eval5.invoke(form-init336568295343421746.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6619) at clojure.lang.Compiler.eval(Compiler.java:6609) at clojure.lang.Compiler.load(Compiler.java:7064) at clojure.lang.Compiler.loadFile(Compiler.java:7020) at clojure.main$load_script.invoke(main.clj:294) at clojure.main$init_opt.invoke(main.clj:299) at clojure.main$initialize.invoke(main.clj:327) at clojure.main$null_opt.invoke(main.clj:362) at clojure.main$main.doInvoke(main.clj:440) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.lang.Var.invoke(Var.java:419) at clojure.lang.AFn.applyToHelper(AFn.java:163) at clojure.lang.Var.applyTo(Var.java:532) at clojure.main.main(main.java:37) ```

Original source