3 ms·
What I would like to see is a `defconstant` macro, which introduces a constant that can not be changed anymore without restarting the JVM. (def x 1) ; x = 1 (d
by Mitt 14y ago
What I would like to see is a `defconstant` macro, which introduces a constant that can not be changed anymore without restarting the JVM.
(def x 1) ; x = 1
(def x 2) ; x = 2 now
(defconstant y 1) ; y = 1
(defconstant y 2) ; Exception
Also a way of fixing functions would be good, so that no lookup is required. Calling such a fixed function has no overhead, it would be a direct call.
- rabidsnail 14y agoVars already default static, so we just need to take better advantage of that in the compiler.
- Mitt 14y agoYes, Clojure 1.4 defaults to static. However, a Var still needs to do an extra lookup at runtime. A Var does not directly point to the object that I want. And Vars have to be that way, this is their core feature. Clojure is a dynamic language, so they need to stay dynamic too. All code constantly assumes that the objects behind Vars will change. Let’s say we have `(defn foo [] 1)`. The caller of (foo) will first lookup the address in RAM of the compiled function, and then jump to it. Because of this dynamicy we can redefine foo at runtime: `(defn foo [] 2)`. All callers still function, and will now get the result `2`. In statically compiled languages this would not happen, because `foo` is translated to the direct address of the first function. The concept of replacing functions at runtime doesn’t exist in that way. But I would like to see an optional “static” programming feature: I want to be able to mark functions as final. This would be nice after major development has happened. A function object that Clojure created could then not be changed any longer, without restarting the JVM. But such functions can be called directly, without any overhead.
- deleted 14y ago[deleted]
- gtrak 14y agoThe jvm can already inline non-final virtual method calls, so getters and setters are free. Are you sure that being able to specify 'static' is a win? Alternatively, you can just use the compile-time capabilities of the macro system to inline your constants as locals.
- gtrak 14y agouser=> (defmacro value [& body] (let [retval# (eval `(do ~@body))] retval#)) #'user/value user=> (macroexpand '(value (+ 1 3))) 4
- simonb 14y agoWell, there is defonce [http://clojure.github.com/clojure/branch-master/clojure.core-api.html#clojure.core/defonce http://clojure.github.com/clojure/branch-master/clojure.core...] As for function lookup, I recommend reading this thread: http://news.ycombinator.com/item?id=2928285 http://news.ycombinator.com/item?id=2928285 Also, vars are by default static (but can be made dynamic with ^:dynamic).
- Mitt 14y ago`defonce` unfortunately doesn’t help. Without restarting the JVM I can overwrite that var. And that is okay, because defonce is just a protection mechanism, to not delete data when a namespace is repeatedly reloaded. This reloading occurs 99% at development time. Useful tool. But I would like to have real constants. A final class with a static final field (and potentially type information), or something like that. This would give the optimal lookup time, as the JVM would have the direct address. When I (defonce x 1) I can still (def x 2), without restarting the JVM. I want this to not be possible with a defconstant.
- zaph0d 14y agoThere is the :const metadata - (def ^:const PI 3.14)