Reputation: 106351
I'm writing some Clojure code that depends upon a number of constants.
They will be used within tight inner loops, so it's important that they will be used and optimised as efficiently as possible by the Clojure compiler+JVM combination. I would normally used a "public static final" constant in Java for the same purpose.
What is the best way to declare these?
Upvotes: 10
Views: 2023
Reputation: 91907
I believe Clojure 1.3 (or maybe 1.4) allows you to put a ^:constant
tag on a def
, signifying to the compiler that this should be a constant and all references should be resolved at compile-time.
Apparently it's Clojure 1.3, and it's ^:const
, not ^:constant
. See How does Clojure ^:const work? for a summary.
Upvotes: 6
Reputation: 1822
If just using def
is not fast enough, you could try creating a let
bound alias before entering your tight loop to avoid going through a var each time.
Upvotes: 3
Reputation: 17299
If really, really, really want the constant in place (I believe, the JIT will notice the value being constant and do the right thing, though), you can use a macro.
(defmacro my-constant [] 5)
This is rather ugly, but performance critical code will always be ugly, I guess.
(do-stuff (my-constant) in-place)
Pay care what you put into the macro, though! I wouldn't this for more than some literal constants. In particular not objects.
Upvotes: 3
Reputation: 15212
There's no defconst
, so just using a global def is idiomatic; as far as optimisation is concerned, the JIT will make things fast.
Upvotes: 3
Reputation: 14671
as said above use def or atom, remember, data is immutable, so if you declare some constants in a list, they don't change.
Upvotes: 2
Reputation: 67760
I think def
-ing things in the global namespace is about as close as you can come.
Upvotes: 6