Conventions, Style, and Usage for Clojure Constants?
Solution 1
From http://dev.clojure.org/display/community/Library+Coding+Standards:
Use earmuffs only for things intended for rebinding. Don't use a special notation for constants; everything is assumed a constant unless specified otherwise.
Solution 2
I don't think there is any hard and fast rules. I usually don't give them any special treatment at all. In a functional language, there is less of a distinction between a constant and any other value, because things are more often pure.
The asterisks on both sides are called "ear muffs" in Clojure. They are usually used to indicate a "special" var, or a var that will be dynamically rebound using binding later. Stuff like out and in which are occasionally rebound to different streams by users and such are examples.
Personally, I would just name it pi
. I don't think I've ever seen people give constants special names in Clojure.
EDIT: Mister Carper just pointed out that he himself capitalizes constants in his code because it's a convention in other languages. I guess this goes to show that there are at least some people who do that.
I did a quick glance through the coding standards but didn't find anything about it. This leads me to conclude that it's really up to you whether or not you capitalize them. I don't think anyone will slap you for it in the long run.
Solution 3
On the computational efficiency front you should know there is no such thing as a global constant in Clojure. What you have above is a var, and every time you reference it, it does a lookup. Even if you don't put earmuffs on it, vars can always be rebound, so the value could always change, so they are always looked up in a table. For performance critical loops this is most decidedly non-optimal.
There are some options like putting a let block around your critical loops and let the value of any "constant" vars so that they are not looked up. Or creating a no-arg macro so that the constant value is compiled into the code. Or you could create a Java class with a static member.
See this post, and the following discussion about constants for more info:
http://groups.google.com/group/clojure/msg/78abddaee41c1227
Solution 4
The earmuffs are a way of denoting that a given symbol will have its own thread-local binding at some point. As such, it does not make sense to apply the earmuffs to your Pi constant.
*clojure-version*
is an example of a constant in Clojure, and it's entirely in lower-case.
Solution 5
Don't use a special notation for constants; everything is assumed a constant unless specified otherwise.
See http://dev.clojure.org/display/community/Library+Coding+Standards
Related videos on Youtube
Julien Chastang
Professional software developer living in beautiful Boulder, Colorado USA
Updated on May 10, 2020Comments
-
Julien Chastang almost 4 years
What are the best practices for defining constants in Clojure in terms of style, conventions, efficiency, etc.
For example, is this right?
(def *PI* 3.14)
Questions:
Should constants be capitalized in Clojure?
Stylistically, should they have the asterisk (*) character on one or both sides?
Any computational efficiency considerations I should be aware of?
-
jemmons about 11 yearsAlso remember that, whatever you end up naming it, your might want to give it const metadata:
(def ^:const pi 3.14)
-
mk12 almost 10 yearsI prefer to just assume everything is a constant unless otherwise specified, as github.com/bbatsov/clojure-style-guide advises.
-
leeor over 8 yearsseems like it would be useful to have a way to make something constant for uses in things like case statements no?
-
-
Ben Richardson over 13 yearsI capitalize my constants, because it's a common convention in other languages. See also
Math/PI
in Java. -
Rayne over 13 yearsI'm sure a few people do, at the very least, but I haven't seen it in any code I've looked at insofar. I don't think there is any of that in core either. It doesn't appear to be a part of the assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards coding standards, so I suppose it's up to the individual.
-
Parv Bhasker over 13 yearshowever i use capitalization for "type" definitions (including structs) to create a conventional, separate name space for them (defstruct Foo :key1)
-
Alex Stoddard over 13 yearsI think "there is no such thing as a global constant in Clojure" is as important philosophically as it is from an efficiency view-point. That said the linked discussion is very helpful in giving a practical example of what is going on with vars.
-
Alex Stoddard over 13 yearsYet it makes no sense to consider
*clojure-version*
thread local. It seems the ear-muffs convention is not as specific as your answer implies. -
Alex Stoddard over 13 yearsAlthough I have just discovered the clojure coding conventions assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards . There the earmuffs style is specified only for things that should be rebound.
-
Anders over 13 yearsYes, rebound/thread local binding. But why clojure-version is supposed to be rebound is beyond me.
-
Anders over 13 yearsWhat are their arguments? The ear-muffs indicate the symbol will be rebound.
-
Corin about 10 yearsIt might go without saying that "Don't use a special notation for constants" means that you should avoid capitalization ...but I said it anyway.
-
Didier A. over 8 yearsThere is, if you add ^:const to a Var it will in-line the Var, that is, it'll look up the value once when the namespace is loaded, and it'll replace everything using the Var with the value itself.
-
amoe about 8 yearsI don't think this argument holds, because regardless of the fact that you're not going to mutate a binding, the benefit of having a convention for constants lies in the implication to the reader that they will be able to find the definition at the top of this or another compilation unit's source file, and this value will be statically determinable before the program runs.
-
Reb.Cabin about 7 yearsDocument for Coding Standards has moved to here dev.clojure.org/display/community/Library+Coding+Standards
-
michaelrbock over 3 yearsIt looks like that link gives a 403 Forbidden error