As a side project I'm creating a Clojure DSL for image synthesis (clisk).
I'm a little unsure on the best approach to function naming where I have functions in the DSL  that are analogous to functions in Clojure core, for example the + function or something similar is needed in my DSL to additively compose images / perform vector maths operations.
As far as I can see it there are a few options:
+) in my own namespace. Looks nice in DSL code but will override the clojure.core version, which may cause issues. People could get confused.my-ns/+). Avoids conflicts, but prevents people from useing the namespace for convenience and looks a bit ugly.v+). Can be used easily and avoid clashes, but the name is a bit ugly and might prove hard to remember.vector-add). Verbose but descriptive, no clashes.clojure.core/+ and redefine with a multimethod + (as georgek suggests). Example code might look something like:
 (show  (v+ [0.9 0.6 0.3] 
             (dot [0.2 0.2 0] 
                  (vgradient (vseamless 1.0 plasma) ))))
What is the best/most idiomatic approach?
first, the repeated appearance of operators in an infix expression requires a nice syntax, but for a lisp, with prefix syntax, i don't think this is as important.  so it's not such a crime to have the user type a few more characters for an explicit namespace.  and clojure has very good support for namespaces and aliasing.  so it's very easy for a user to select their own short prefix: (x/+ ...) for example.
second, looking at the reader docs there are not many non-alphanumeric symbols to play with, so something like :+ is out.  so there's no "cute" solution - if you choose a prefix it's going to have to be a letter.  that means something like x+ - better to let the user choose an alias, at the price of one more character, and have x/+.
so i would say: ignore core, but expect the user to (:require .... :as ...).  if they love your package so much they want it to be default then they can (:use ...) and handle core explicitly.  but you choosing a prefix to operators seems like a poor compromise.
(and i don't think i have seen any library that does use single letter prefixes).
one other possibility is to provide the above and also a separate package with long names instead of operators (which are simply def'ed to match the values in the original package).  then if people do want to (:use ...) but want to avoid clashes, they can use that (but really what's the advantage of (vector-add ...) over (vector/+ ...)?)
and finally i would check how + is implemented, since if it already involves some kind of dispatch on types then georgek's comment makes a lot of sense.
(by "operator" above i just mean single-character, non-alphanumeric symbol)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With