How to construct existing function names in Clojure?

clojure

#1

I have a DB namespace for each DB table, and each namespace includes functions called CREATE, READ, UPDATE, and DELETE. I am defining routes that correspond to these functions and want to be able to iterate through then namespaces and contruct the full function reference. I am able to create a symbol that LOOKS like the function reference, but it isn’t the real function and fails in practice. How can this be done (and does it need to be done with a macro)? Here’s what I have tried:

(defn crud-routes
  ""
  []
  (into []
        (for [ns ["agroups" "attachments" "categories" "categorylinks" "clients" "computers" "core" "departments" "devices" "flaglinks" "flags" "grouplinks" "histories" "jobs" "knowledgebases" "logs" "memo" "memos" "migratus" "permissionlinks" "permissions" "pictures" "queries" "searches" "stats" "techs" "users" "works"]]
          [(str "/" ns) {:get #(response/ok "got me";((eval (symbol (str ns "/READ"))))
                                )
                         :post (symbol (str ns "/CREATE")) 
                         :patch (symbol (str ns "/UPDATE"))
                         :delete (symbol (str ns "/DELETE"))}])))

#2

Have you considered traversing the namespaces and invoking from there?

(ns scratch.ns-traverse)

;; Can we explore what exists in some namespace?

(defn POST []
  :posted)
(defn GET []
  :gotten)

(ns-publics *ns*)
;; => {POST #'scratch.ns-traverse/POST, GET #'scratch.ns-traverse/GET}

((-> (ns-publics *ns*)
     (get 'POST)))
;; => :posted

Trying to figure out how I can make something work without using the current namespace (*ns*) now.


#3

For different namespaces than the current one, you might want to do something like this:

((-> (find-ns 'scratch.ns-traverse)
     ns-publics
     (get 'POST)))
;; => :posted
  • find-ns tries to resolve a namespace you’ve declared from a symbol
  • ns-publics gives you public symbols. ns-interns includes private vars.
  • Then you can use the normal Clojure map as you wish!

More information: https://8thlight.com/blog/aaron-lahey/2016/07/20/relationship-between-clojure-functions-symbols-vars-namespaces.html