On a particular namespace I am working on I am beginning to run out of function names. Is there a way to get a warning like the one I get if I override a symbol from another namespace if I reuse a symbol which is already bound to a function in the same namespace?
If this is enough of a problem that you'd be willing to replace a (set of) core macro(s), you could try this approach:
(ns huge.core
(:refer-clojure :exclude [defn]))
(defmacro defn [name & defn-tail]
(assert (nil? (resolve name))
(str "Attempting to redefine already defined Var "
"#'" (.name *ns*) "/" name))
`(clojure.core/defn ~name ~#defn-tail))
Then any attempt to redefine an existing Var with defn will fail:
user=> (defn foo [] :foo)
#'user/foo
user=> (defn foo [] :bar)
AssertionError Assert failed: Attempting to redefine already defined Var #'user/foo
(nil? (resolve name)) user/defn (NO_SOURCE_FILE:2)
You could similarly replace defmacro; in that case you would have to call clojure.core/defmacro when defining your own variant.
Plain, unadorned def is a special form and receives magic treatment from the compiler, so you could still overwrite existing Vars with it. If you would like to guard against name clashes on that flank too, you could switch to something like defvar (used to be available in clojure.contrib.def) with a similar custom assert.
This isn't quite an answer to your question but may help avoid the issue depending on how the functions in your namespace are being used. You could make them into local functions using letfn, allowing you to reuse names for functions that are only used within the context of another function.
(defn main-fn [x]
(letfn [(secondary-fn [x] (* x x))
(another-fn [x] (secondary-fn (inc x)))]
(/ (another-fn x) 4)))
Even if you restrict yourself to single-character function names, you are in no danger of running out, as there are (about) 64 thousand Unicode characters, any one of which is a valid function name.
Given that you can in fact have names that are ten thousand characters long, you are on even safer ground.
Related
I would like to execute some Clojure code that depends upon a certain var, but only if that var is defined. As a simplified example, the body of the if form should only be executed if sym is defined:
(if (resolve 'sym) (println sym))
Unfortunately, this doesn't work. If sym is not defined, the compiler still tries to resolve it and throws:
CompilerException java.lang.RuntimeException: Unable to resolve symbol: sym in this context
From reading Rich Hickley's comment here, I gathered that this behavior is due to Clojure's use of (mostly) single-pass compilation. However, as much sense as that makes, it obviously results in undesirable behavior in this case.
I can get around the problem by forcing the symbol resolution to happen at runtime:
(if (resolve 'sym) (println (deref (resolve 'sym))))
But this is an undesirable hack. Is there a better way, or is it not possible with Clojure's read-eval model?
(Why do I need to do this? I have multiple composable profiles defined in my profiles.clj. One of them is for vinyasa, which allows me to inject various functions into the conveniently accessible . namespace. Others load various other utility libraries. In the profiles for those other utility libraries, I want to use vinyasa to inject the most important functions, but only if vinyasa is loaded. I am currently using a variation of the hack above.)
The approach recommended by #Michiel with when-let is the best way to solve this problem. Importantly, you can make the conditionality almost completely transparent by using let's ability to shadow an existing binding:
(when-let [foo (resolve 'foo)]
(foo))
;;=> nil
(defn foo []
:bar)
(foo)
;;=> :bar
(when-let [foo (resolve 'foo)]
(foo))
;;=> :bar
(defn get-when-var-defined [sym]
(when-let [var-for-sym (resolve sym)]
#var-for-sym))
(get-when-var-defined 'foo) ;;=> nil
(def foo 1)
(get-when-var-defined 'foo) ;;=> 1
;; Once upon a time I opened a REPL and wrote a protocol
;; definition:
(defprotocol SomeProtocol
(f [this]))
;; And a record:
(defrecord SomeRecord []
SomeProtocol
(f [this]
"I don't do a whole lot."))
;; And a very useful side-effect free function!
(defn some-function []
(f (SomeRecord.)))
;; I call my function...
(some-function)
;; ...to see exactly what I expect:
;; user=> "I don't do a whole lot."
;; Unsatisfied with the result, I tweak my record a little bit:
(defrecord SomeRecord []
SomeProtocol
(f [this]
"I do a hell of a lot!"))
(some-function)
;; user=> "I don't do a whole lot."
Looks like a bug to me. I just cannot be sure after having seen so
many false compiler bug reports in c++ user group.
You need to re-define the some-function after redefining the record again. The reason for this is that defrecord creates a new type (using deftype) and using the (SomeRecord.) notation inside the function will bind the code to that type even after a new type with same name is defined. This is why it is usually prefer to use (->SomeRecord) notation to instantiate the record, using this notation will make your code work like you expected.
I am trying to dynamically create functions based on some static public fields of a Java class. So in one file I have something like:
(intern *ns* (symbol (get-fieldname-from-class class)) some-func)
The problem is that I want to call that particular function while it isn't defined yet.
For example, the Java class has a static int PARENTHESIZED_EXPRESSION field. From this I generate a parenthesized-expression? function. This works quite nice, but when I load a Clojure file in the REPL that uses this functions I get an
unable to resolve parenthesized-expression?
error. So I have to make sure that the symbol's are interned first. How can I do this?
I realize this is not a very functional approach, but I'm a little bit hesitant to enter almost 80 similar functions for all the fields of this class. Besides, this class might be subject to change.
I wonder if you could get by using a macro like this:
user=> (defmacro f [sym] `(defn ~(symbol (str sym "?")) [x#] (= x# ~(symbol (str "java.util.Calendar/" (str sym))))))
#'user/f
user=> (f DAY_OF_MONTH)
#'user/DAY_OF_MONTH?
user=> (DAY_OF_MONTH? java.util.Calendar/DAY_OF_WEEK)
false
user=> (DAY_OF_MONTH? java.util.Calendar/DAY_OF_MONTH)
true
user=>
I have been looking at the source for defmacro which uses "let" in its definition:
(def
^{:doc "Like defn, but the resulting function name is declared as a
macro and will be used as a macro by the compiler when it is
called."
:arglists '([name doc-string? attr-map? [params*] body]
[name doc-string? attr-map? ([params*] body)+ attr-map?])
:added "1.0"}
defmacro (fn [&form &env
name & args]
(let [prefix (loop [p (list name) args args]
However, "let" is defined as a macro itself:
(defmacro let
"binding => binding-form init-expr
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein."
{:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
[bindings & body]
(assert-args
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "an even number of forms in binding vector")
`(let* ~(destructure bindings) ~#body))
Can someone explain how this works as I can't understand how "defmacro" can be defined in terms of things which need "defmacro" to already be defined. (if that makes sense :)
This is possible because before defining defmacro function in core.clj there is already a definition of let at this location (which gets redefined later). Macros are just normal functions and the var they are bound to has meta data key :macro with value true so that at compile time the compiler can differentiate between a macro (which execute at compile time) with a function, without this meta key there is no way to differentiate between a macro and a function because macro itself is a function that happens to process S-expressions.
recusrive macros work fine and occur in many place in both the clojure language core and in other programs. macros are just functions that return S-Expressions, so they can be recursive just as functions can. In the case of let in your example it's actually caling let* which is a different function (its fine to have * in a functions name), so although recursive macros are fine, this doesn't happen to be an example of them
How can I test wether a variable has been declared or assigned (i.e. check if "a" is defined, when I expect a program to call some code like this (def a (create-a)) ?
And related --- how does the answer to this question relate to the problem of resolving a symbol (i.e. a function) which has been declared ? Clojure: determine if a function exists
It seems like a defined variable should be checkable in the same sense that a defined function is, but I'm finding that the solution for determining if a function exists is not sufficient for determining wether a variable exists.
Some context : I'm writing unit tests for a multideveloper project, and want to make sure that the test data, and the methods in different classes have been defined. Since there is no good IDE support for clojure, it seems to me that, given its loose structure, it is good to test method names and variable names existence before testing their outputs / content.
You can use resolve to see if the variable was bound/defined:
(resolve 'meaning)
nil
(def meaning 42)
#'user/meaning
(resolve 'meaning)
#'user/meaning
or you can boolean check it, if you need true/false:
(boolean (resolve 'meaning))
true
One way to do this is to use ns-resolve, for example:
user=> (def a "hello a")
user=> (ns-resolve *ns* 'a)
#'user/a
user=> (ns-resolve *ns* 'b)
;nil ; This assumes b hasn't been defined before...
Note that if you namespace-qualify the symbol to be checked then what you pass as first argument (*ns* in the example above) doesn't matter:
user=> (ns-resolve 'user 'a)
#'user/a
user=> (ns-resolve 'other 'a)
nil
user=> (ns-resolve 'other 'user/a)
#'user/a
The resolve function mentioned by #tolitius is actually a shorthand for ns-resolve where the namespace argument always evaluates to ns, depending on the use case it might be more handy.
As others have said, resolve will return the var for a symbol if there is one defined, or nil. Further, you can check if the var has a value bound to it by using bound?.
user=> (resolve 'foo)
nil
user=> (def foo)
#'user/foo
user=> (resolve 'foo)
#'user/foo
user=> (bound? #'foo)
false
user=> (def foo 5)
#'user/foo
user=> (bound? #'foo)
true
Since there is no good IDE support for clojure it seems to me that,
given its loose structure, it is good to test method names and
variable names existence before testing their outputs / content.
This is nuts. You really want a test to say "Oops! You forgot to define foobar!" instead of just trying to run foobar and seeing Clojure's "Unable to resolve symbol" message?
What do you gain from this? You lose the stacktrace, which could be useful if, for example, the test is passed the wrong function name by some other code. Much better to know what line mis-spelled foobar than to search through your whole test namespace.