Do stars have a specific meaning when used in defining symbols (such as in functions, bindings etc.)? Is it just a normal binding name when i define something like:
(def *clojure* "CLOJURE")
As i def this i get in the REPL:
Warning: *clojure* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *clojure* or change the name.
Where can i read learn more about the special characters and things like **?
By convention, variables with 'earmuffs' (i.e. enclosed by *s) are dynamic vars which can be rebound using binding and related functions e.g.
(def ^:dynamic *dyn*)
(binding [*dyn* "Hello world!"]
(println *dyn*))
if you name a variable in this way without making it dynamic you get the warning you're seeing.
Check this clojure style guide. Earmuffs are just one type of convention as already been mentioned by #Lee.
Related
In Common Lisp it's easy
http://clhs.lisp.se/Body/v_ld_pns.htm
because the special variable is being set at the load time.
However, I don't seem to be able to find how to do it in Clojure. Is there a way to find which file was passed to load-file?
The load-file function eventually reaches Compiler.java#L7395, where it dynamically binds the source name (when it exists) to the variable designated by SOURCE (see Compiler.java#L235), a.k.a. clojure.core/*source-path*.
In /tmp/test.clj:
(print clojure.core/*source-path*)
In the REPL:
user=> (load-file "/tmp/test.clj")
test.cljnil
In clojure, What is the best possible way to declare a global variable, the value of which needs to be changed in a function and this global variable need to be accessed in other namespaces
Ex:
(ns ..main
.....)
(def global_variable nil)
..
(defn main ...
Change the value of global variable here
)
Another name space
(ns accessvariable ...)
(println (main/global_variable))
What is the best way to do this?
Just store an atom in your global var:
(def global-var (atom nil))
Note: this is in response to the third comment on the question. dAni's answer applies to the question as asked.
Idiomatic Clojure favors functions whose outputs are determined only by their input parameters. This is in contrast to a function which relies on its parameters and global state, too. It is easy to convert a function which uses global data into one that does not - you just need to add a parameter that will contain the data. For example: instead of (defn print-global [] (println #global-atom-defined-elsewhere)), you use (defn print-my-val [val] (println val)).
If you use the command line argument extremely frequently, you might still find it more convenient to put the data in a global atom, instead of having everything use it as a parameter. This is up to you.
When I use some long function names, I used the use form, like this:
(use '[clojure.string :as str])
But I don't know why add a single quote ' to the vector, so I tried to figure out its type:
(type '[clojure.string :as str])
;=> clojure.lang.PersistentVector
Simplified example:
(type ["hello"])
;=> clojure.lang.PersistentVector
(type '["hello"])
;=> clojure.lang.PersistentVector
It seems the single quote doesn't change anything, can anybody explain the usage of it in the use form?
The intent is to quote the symbols. This way they'll be treated as symbols, and use can take those symbols as naming a namespace to load and pull into the current. You want to avoid the default treatment of a symbol, which is resolving it as the name of a Var and using the value of that Var. You can also do this as
(use ['clojure.string :as 'str])
but that involves some unnecessary typing; quoting the whole vector makes you less likely to forget anything. Particularly if you're doing anything with :only, :refer or similar keyword arguments.
Aside: ns doesn't need this because as a macro it can control evaluation of its arguments - functions like require and use have all their arguments read and evaluated before they themselves run. This is part of the reason why ns is normally preferred over those functions.
use is a function, hence the evaluator evaluates its arguments before they are passed (applicative order evaluation).
You don't want [clojure.string :as str] to be evaluated as the evaluator would try to resolve the symbols in it with no success before applying use.
Hence quote (reader shorthand ') is there to prevent their evaluation.
According to spec, def should intern the var in the current ns (i.e. *ns*). However, the following code does not look anything like it:
(ns namespace-b)
(defn def_something []
(ns namespace-a)
(println *ns*) ;prints namespace-a as it should
(def something 1)
)
(def_something)
(println namespace-b/something) ; prints 1
(println namespace-a/something) ; throws
What am I missing?
Notes:
defn is used just for clarity. Defining and running anonymous function works just as well.
I know that using def inside function is probably not very idiomatic. However, this is just extracted essence of a bigger problem I ran into.
The parser already interns the var to the current namespace at compile time, although it won't be bound immediately:
(defn dd [] (def x 0))
x ;; => #<Unbound Unbound: #'user/x>
The relevant piece of code can be found here, with the second parameter to lookupVar triggering the aforementioned interning for non-existing vars here.
The parses then generates an expression that references the previously created var, so the expression logic never leaves the current namespace.
TL;DR: def is something that the compiler handles in a special kind of way.
The key thing to understand about def is that it is a macro. This means that it does not resolve the namespace or create the binding at runtime, but beforehand, while the code is being compiled.
If you call a function that calls def, that call to def was already resolved to use the namespace in which the function was defined. Similarly, if you call functions inside a function body, the functions to call are resolved at compile time within the namespace where that function was defined.
If you want to generally bind values to namespaces at runtime, you should use the function intern, which lets you explicitly set the namespace to mutate.
All this said, namespace mutation is just that, it's procedural and is not thread safe and does not have nice declarative semantics like other options Clojure makes available. I would strongly suggest finding a way to express your solution that does not involve unsafe runtime mutation.
What is the rationale for Symbols in Clojure to be bound to an underlying object and have an optional separate value ? Perhaps something elementary I am missing but would be great if someone could point out the Why.
General intro:
Symbols in any Lisp are used as identifiers. If you're going to refer to the value of a variable, say, you need to have a way of naming it; that's what symbols are for. Remember that all Lisp code gets translated at read time to Lisp data structures; identifiers must also be represented by some data structure and it happens to be the symbol. Upon encountering a symbol, eval dispatches to some kind of a "name lookup" operation.
Moving from Lisp generalities to Clojure particulars, the behaviour of the Clojure eval / compiler is that upon encountering a symbol, it takes it to be a name for either a let-introduced local variable or function parameter or the name of an entry in a namespace. Actually only non-namespace-qualified symbols may be used in the first capacity (meaning symbols of the form foo and not some-namespace/foo).
A roughly sketched example:
For a non-namespace-qualified symbol foo, if a let binding / function parameter of name foo is found, the symbol evaluates to its value. If not, the symbol gets transformed to the form *ns*/foo (*ns* denotes the current namespace) and an attempt is made to look up a curresponding entry in *ns*; if there is such an entry, its value is returned, if not, an exception is thrown.
Note that a symbol like identity, when used in namespace quux, will be resolved to clojure.core/identity through an intermediate step in which an entry under quux/identity is discovered; this will normally refer to clojure.core/identity. That's an implementation detail one doesn't think of when coding intuitively, but which I find impossible not to mention when trying to explain this.
A symbol which is already namespace-qualified (something like a zip/root in a namespace which refers to clojure.zip without use'ing it) will be looked up in the appropriate namespace.
There's some added complexity with macros (which can only occur in operator position), but it's not really something relevant to the behaviour of symbols themselves.
Vars vs Symbols:
Note that in Clojure, symbols are not themselves storage locations -- Vars are. So when I say in the above that a symbol gets looked up in a namespace, what I mean is that eval looks up the Var named by the symbol resolved to its namespace-qualified form and then takes the value of that. The special form var (often abbreviated to #') modifies this behaviour so that the Var object itself is returned. The mechanics of symbol-to-Var resolution are unchanged, though.
Closing remarks:
Note that all this means that symbols are only "bound" to objects in the sense that eval, when evaluating a symbol, goes on to look for some further object. The symbol itself has no "slot" or "field" for an object to be bound to it; any impression that a symbol is "bound" to some object is due to eval's workings. This is a Clojure characteristic, as in some Lisps symbols do themselves act as storage locations.
Finally, one can use the usual quoting mechanism to prevent the evaluation of a symbol: in 'foo, the symbol foo will not be evaluted (so no name lookup of any sort will be performed); it'll be returned unchanged instead.
In response to OP's comment: Try this for fun:
(defmacro symbol?? [x]
(if (symbol? x)
true
false))
(def s 1)
(symbol? s)
; => false
(symbol?? s)
; => true
(symbol? 's)
; => true
(symbol?? 's)
; => false
The last one explained: 's is shorthand for (quote s); this is a list structure, not a symbol. A macro operates on its arguments passed in directly, without being evaluated; so in (symbol?? 's) it actually sees the (quote s) list structure, which is of course not itself a symbol -- although when passed to eval, it would evaluate to one.
There may be some confusion here from the different usages of the term "symbol" in Common Lisp and in Clojure.
In Common Lisp, a "symbol" is a location in memory, a place where data can be stored. The "value" of a symbol is the data stored at that location in memory.
In Clojure, a "symbol" is just a name. It has no value.
When the Clojure compiler encounters a symbol, it tries to resolve it as
a Java class name (if the symbol contains a dot)
a local (as with "let" or function parameters)
a Var in the current Namespace
a Var referred from another Namespace
The Var, as a previous poster pointed out, represents a storage location.
There are good reasons why Clojure separates Vars from Symbols. First, it avoids the annoyance of Common Lisp's automatically-interned symbols, which can "pollute" a package with unwanted symbols.
Secondly, Clojure Vars have special semantics with regard to concurrency. A Var has a exactly one "root binding" visible to all threads. (When you type "def" you are setting the root binding of a Var.) Changes to a Var made within a thread (using "set!" or "binding") are visible only to that thread and its children.