Clojure: issues getting the symbol of a function in a looping context

為{幸葍}努か 提交于 2019-12-25 12:46:13

问题


Let's take that Clojure code:

  (defn ^{:test-1 "meta-test-1"} fn-key-1 
    [x]
    (eval nil))

  (defn ^{:test-2 "meta-test-2"} fn-key-2 
    [x]
    (eval nil))

  (def some-map {fn-key-1 "test-1"
    fn-key-2 "test-2"})

As you can see, the keys of my map are Symbols that refers to functions. I don't thing there is anything special there.

As you can see, when defining the map the keys of my map are Symbols that refers to functions. However, when they are read by the reader, then they get resolved to the function objects.

Now, what I want to do is to iterate over my some-map map to get the meta-data for each of the keys.

I was thinking doing this that way:

  (defn some-fn 
    [m]
    (doseq [[fn-key value] m]
      (println (meta fn-key))))

However, what is being printed here is nil. This is expected since the meta-data is defining the symbol, and not the function. So, there is no meta-data attached to the function and it is why nil is being returned/printed.

So this lead to a question: is it possible to get the symbol that refers to my function "fn-key" in that context?

In that doseq loop, it appears that fn-key is a function and not the symbol of that function. What I need is a way to get the symbol of that function such that I can use (meta (get-symbol fn-key)).

Question Resolution

This question got resolved by defining the functions that way:

(def fn-key-1
  (with-meta (fn [x] (eval nil)) {:foo "bar"}))

(def fn-key-2
  (with-meta (fn [x] (eval nil)) {:foo "bar"}))

Revision of the Resolution

I revised the solution above to make it cleaner. In fact, if you were to type fn-key-1 in the REPL, you were to get an anonymous function reference such as #< clojure.lang.AFunction$1@15ab1764>. The problem with that is that it make things difficult to debug when you don't know what is being evaluated. To solve this issue, I changed the two function definitions to use this syntax, which resolve this issue:

(def fn-key-1 ^{:foo "bar"} (fn [x] (eval nil)))

(def fn-key-2 ^{:foo "bar"} (fn [x] (eval nil)))

Now, if we type fn-key-1 then we will get something like #<core$foo user.core$foo@66e37466> instead. At least, we have the namespace & symbol signature of this function object.


回答1:


(def some-map {#'fn-key-1 "test-1"
               #'fn-key-2 "test 2"})

fn-key-1 is resolved by the reader to the function object (which has no metadata to query). #'fn-key-1 resolves to the var itself, and holds the metadata.



来源:https://stackoverflow.com/questions/24000510/clojure-issues-getting-the-symbol-of-a-function-in-a-looping-context

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!