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 use
ing the namespace for convenience and looks a bit ugly.v+
). Can be use
d 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