tags:

views:

124

answers:

4

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?

+8  A: 

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.

Rayne
I capitalize my constants, because it's a common convention in other languages. See also `Math/PI` in Java.
Brian Carper
I'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 http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards coding standards, so I suppose it's up to the individual.
Rayne
however i use capitalization for "type" definitions (including structs) to create a conventional, separate name space for them(defstruct Foo :key1)
jneira
+7  A: 

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

pjstadig
I 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
+4  A: 

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.

Anders
Yet 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
Although I have just discovered the clojure coding conventions http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards . There the earmuffs style is specified only for things that should be rebound.
Alex Stoddard
Yes, rebound/thread local binding. But why *clojure-version* is supposed to be rebound is beyond me.
Anders
A: 

According to the "Practical Clojure" book, it should be named *pi*

Aymen
What are their arguments? The ear-muffs indicate the symbol will be rebound.
Anders