Injecting functions to a library

Hi,

what do you think is the idiomatic way to inject functions to a library. The library uses these functions internally, but these are so basic that I don’t want to pass them as arguments to the library functions. The application has to provide these functions once on startup. Then the library uses them.

An example:
Given a web application foo (cljs) and a server application bar (clj) which both use mylib (cljc). Both applications want mylib to use an application specific function to log warnings. Therefor these applications call (mylib/configure {:warn-fn warn}).

But how should mylib “store” the :warn-fn function? Using an atom seams overkill, since the value will never be changed.

Most of the libraries I work with that support some sort of setup register! or configure! type operation use atoms internally. I think it’s a reasonable choice. You can declare the internal state with a default value and it can be replaced or modified safely (atomically) via function calls.

2 Likes

You could add a multimethod to the library and then add :default implementations in the apps?

;; in cljc lib
(ns mylib)
(defmulti warn :please-provide-a-default)
(defn useful-fn-that-warns [] .... (warn "some xyz warning") ....)

;; in foo cljs app
(ns foo
  (:require [mylib]))
(defmethod mylib/warn :default [message] (println "logged by foo:" message))
(mylib/useful-fn-that-warns) ;; => logged by foo: some xyz warning

;; in bar clj app
(ns bar
  (:require [mylib]))
(defmethod mylib/warn :default [message] (println "logged by bar:" message))
(mylib/useful-fn-that-warns) ;; => logged by bar: some xyz warning

(Heavily edited from previous garbled attempt. 3rd time lucky?)

When I extended Specter to utilize a javascript-particular concern, it was made possible by their use of multimethods, which was good.

On the other hand, when I adjusted deja fu to work with a different time data type, it was by altering an atom.

So, I’ve appreciated either one!

I also think the atom approach is absolutely fine, and there’s really nothing overkill about it. However in your particular case why not just use reader conditionals?

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.