That’s why Clojure has the backquote, which resolves symbols as it reads the list.
`(or (satisfies list?)
(and Integer (not (satisfies odd?))))
That said, if you were using satisfies
as a magic symbol and not as a real pointer to a satisfies function, they’d need to escape that from being resolved.
Like in this scenario, is the satisfies
supposed to point to a var from your.lib ? Or the user namespace? Or neither, and you interpret that symbol as is in your code?
(ns my.ns
(:require [your.lib :as l]))
(defn satisfies [a b] (println a b))
(l/define
`(or (satisfies list?)
(and Integer (not (satisfies odd?)))))
If it refers to a var in your.lib, the user should do:
(l/define
`(or (l/satisfies list?)
(and Integer (not (l/satisfies odd?)))))
So it gets resolved to the right thing when backquoted. If it was supposed to refer to the var they defined, then you’d keep it how it was. But if you want it to be interpreted they’d need to do:
(l/define
`(or (~'satisfies list?)
(and Integer (not (~'satisfies odd?)))))
So I’ve seen people prefer keywords in those cases:
(l/define
`(or (:satisfies list?)
(and Integer (not (:satisfies odd?)))))
Or I’ve seen people define in their lib a var of the symbol that returns the unqualified symbol or keyword like:
(ns your.lib)
(def satisfies 'satisfies)
(ns my.ns
(:require [your.lib :as l :refer [satisfies]]))
(l/define
`(or (satisfies list?)
(and Integer (not (satisfies odd?)))))
In my opinion this, or having your code resolve things at the place it is given would be best.
The thing is, when the user provides unqualified symbols, that’s just not the real pointer. It’s like a shortname. So if you did that, you could bank on the fact their won’t be conflict, or do what CL does, and do a search but if you find conflicts throw an error and then ask them to explicitly shadow the one they want. And similarly you could let them define nicknames too.
(ns my.ns
(:require [your.lib :as l])
(l/set-types!
{'list? `list?
'odd `odd?
'Integer `Integer})
(l/define
`(or (satisfies list?)
(and Integer (not (satisfies odd?)))))
As an aside, I’m still confused how you solved it in Common-lisp?
What happens if someone gives you a shadowing-import
symbol? Or if they use a package local nickname?