Conventions, Style, and Usage for Clojure Constants?

前端 未结 8 1223
余生分开走
余生分开走 2021-02-02 06:48

What are the best practices for defining constants in Clojure in terms of style, conventions, efficiency, etc.

相关标签:
8条回答
  • 2021-02-02 07:07

    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

    0 讨论(0)
  • 2021-02-02 07:08

    In Common Lisp, there's a convention of naming constants with plus signs (+my-constant+), and in Scheme, by prefixing with a dollar sign ($my-constant); see this page. Any such convention conflicts with the official Clojure coding standards, linked in other answers, but maybe it would be reasonable to want to distinguish regular vars from those defined with the :const attribute.

    I think there's an advantage to giving non-function variables of any kind some sort of distinguishing feature. Suppose that aside from variables defined to hold functions, you typically only use local names defined by function parameters, let, etc. If you nevertheless occasionally define a non-function variable using def, then when its name appears in a function definition in the same file, it looks to the eye like a local variable. If the function is complex, you may spend several seconds looking for the name definition within the function. Adding a distinguishing feature like earmuffs or plus signs or all uppercase, as appropriate to the variable's use, makes it obvious that the variable's definition is somewhere else.

    In addition, there are good reasons to give special constants like pi a special name, so no one has to wonder whether pi means, say, "print-index", or the i-th pizza, or "preserved interface". Of course I think those variables should have more informative names, but lots of people use cryptic, short variable names, and I end up reading their code. I shouldn't have to wonder whether pi means pi, so something like PI might make sense. None would think that's a run of the mill variable in Clojure.

    0 讨论(0)
  • 2021-02-02 07:11

    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

    0 讨论(0)
  • 2021-02-02 07:14

    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.

    0 讨论(0)
  • 2021-02-02 07:19

    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.

    0 讨论(0)
  • 2021-02-02 07:24

    Clojure has a variety of literals such as:

    3.14159
    :point
    {:x 0 
     :y 1}
    [1 2 3 4]
    #{:a :b :c}
    

    The literals are constant. As far as I know, there is no way to define new literals. If you want to use a new constant, you can effectively generate a literal in the code at compile-time:

    (defmacro *PI* [] 3.14159265358979323)
    (prn (*PI*))
    
    0 讨论(0)
提交回复
热议问题