Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure caret as a symbol?

Tags:

clojure

caret

So I thought it would be a nice idea to name a function that calculates the exponential ^, but it seems like the caret actually does something special, as the Clojure REPL generates an error when evaluating '^. Googling mostly gave me this, so I was wondering what the actualy use for the caret in Clojure is.

(Also, would it be possible after all to name a function ^?)

like image 676
wrongusername Avatar asked Jan 19 '12 01:01

wrongusername


People also ask

What are symbols in Clojure?

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.

What is clojure form?

Clojure (/ˈkloʊʒər/, like closure) is a dynamic and functional dialect of the Lisp programming language on the Java platform. Like other Lisp dialects, Clojure treats code as data and has a Lisp macro system.


1 Answers

^ is "the meta character" it tells the reader to add the symbol starting with ^ as metadata to the next symbol (provided it is something that implements IMetas)

user=> (def x ^:IamMeta [1 2 3]) #'user/x user=> x [1 2 3] user=> (meta x) {:tag :IamMeta} user=>  

You can learn a lot about how clojure works under the hood by looking at the meta of things, for instance functions:

user=> (meta foo)                           {:ns #<Namespace user>,   :name foo, :file "NO_SOURCE_PATH",   :line 5, :arglists ([s])} 

this is very often used for type hints

(defn foo [^String s] (.charAt s 1)) 

it is generally a good idea to turn on reflection warnings (set! *warn-on-reflection* true) and then add type hints until the warnings go away. without these Clojure will look up the type of the function operands at run-time, which saves you the trouble of fussing with types though at a slight cost.

PS: My next favorite reader character is the "dispatch" character #, it is well worth learning about it next :)

PPS: this is different in clojure 1.2.x vs clojure 1.3.x in Clojure 1.2.1 metadata does not compose when you use the meta-character:

user=> (def foo ^:foo ^:bar [1 2 3]) #'user/foo user=> (meta foo) {:tag :foo} 

and in 1.3 it "does the right thing" and also keywords are options instead of "tags":

user=> (def foo ^:foo ^:bar [1 2 3]) #'user/foo user=> (meta foo) {:foo true, :bar true} 
like image 78
Arthur Ulfeldt Avatar answered Sep 18 '22 00:09

Arthur Ulfeldt