u6f6o
u6f6o

Reputation: 2190

How to uniquely identify a given clojure function?

I am currently working on a simple event dispatcher for a minesweeper game I've written in clojure.

As a starting point I thought about having something like:

(def receivers (atom {}))

With a register function that appends a given function to a particular map of events with a nested set per event, e.g. {:do-sth #{func1 func2}}

As I learned, as soon as you add a function again to the namespace, it had a different identity, which of course makes sense but lets my approach fail.

Is there a way to uniquely identify a function that might be passed in as parameter? Otherwise I'd have to provide a unique id for every function which I'd like to avoid if possible.

UPDATE

Going with the suggestion from clyfe, I ended up with the following first approach:

(def receivers (atom {}))

(defn register 
  [event wrapped-function]
  (if 
    (var? wrapped-function)    
    (swap! receivers 
           #(assoc %1 %2 (conj (or (get %1 %2) #{}) %3))
           event 
           wrapped-function)
    (throw (IllegalStateException. 
            "wrapperd function must be a var"))))


(defn bar
  []
  "bar")


(register :foo #'bar)

Upvotes: 0

Views: 74

Answers (1)

clyfe
clyfe

Reputation: 23770

If the problem is due to code reloading, you can store the function's enclosing var in the set {:ev #{#'f1 #'f2}}, that stays the same after reloading:

user=> (defn foo [] 1)
#'user/foo
user=> foo
#<user$foo user$foo@540e6cef>
user=> (def f1 foo)
#'user/f1
user=> (def f2 #'foo)
#'user/f2
user=> (defn foo [] 2)
#'user/foo
user=> foo
#<user$foo user$foo@35d4a23f>
user=> (f1)
1
user=> (f2)
2

Upvotes: 1

Related Questions