質問

I want to pass in a symbol as a parameter to a function and have that symbol captured as either quoted or a string so it can be concatenated with -a tagged on at the end and then use the newly generated symbol to define an atom. But is there some way to do this before the symbol gets evaluated?

(defn sym-a [variable] (symbol (str variable "-a")))


   (defn sym-val [old-sym]
      (let [ new-sym (sym-a old-sym)]
        `(def ~new-sym (atom nil))))

It works when I use a macro, but I wonder if there is some way to avoid this?

(defmacro sym-val [old-sym]
   (let [ new-sym (sym-a old-sym)]
    `(def ~new-sym (atom nil))))
役に立ちましたか?

解決

When a symbol is evaluated, it is resolved in the current binding context unless you explicitly prevent evaluation using quote or its shorthand '.

e.g.:

(def foo-log 42)
(log-name foo)
;; CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(/tmp/form-init735849253251327390.clj:1:1)

(log-name 'foo)
=> foo-log

(eval (log-name 'foo))
=> 42

You can write a macro, where the parameter list is not evaluated and return the created symbol for evaluation.

(defmacro log-name-macro
  [channel-name]
  (log-name channel-name))

(log-name-macro foo)
=> 42

In your example, you would now be required to write log-put as a macro.

I don't recommend this approach to solving your problem at all.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top