Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hidden features of Clojure

Tags:

clojure

Clojure has an immutable, persistent queue datatype, PersistentQueue, but it doesn't (yet?) have literal reader syntax or Clojure wrapper functions, so you have to create one via a Java call. Queues conj (push) onto the rear and pop from the front with good performance.

user> (-> (clojure.lang.PersistentQueue/EMPTY)
          (conj 1 2 3)
          pop)
(2 3)

Lists conj onto the front and pop from the front. Vectors conj onto the rear and pop from the rear. So queues are sometimes exactly what you need.

user> (-> ()
          (conj 1 2 3)
          pop)
(2 1)
user> (-> []
          (conj 1 2 3)
          pop)
[1 2]

(defn foo [a & [b c]] ...)

You can destructure the rest argument.

Update:

The latest commit to the git repo (29389970bcd41998359681d9a4a20ee391a1e07c) has made it possible to perform associative destructuring like so:

(defn foo [a & {b :b c :c}] ...)

The obvious use of this is for keyword arguments. Note that this approach prevents mixing keyword arguments with rest arguments (not that that's something one's likely to need very often).

(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)

If you want default values for keyword arguments.


The read-eval reader macro: #=

(read-string "#=(println \"hello\")")

This macro can present a security risk if read is used on user input (which is perhaps a bad idea on its own). You can turn this macro off by setting *read-eval* to false.


You can apply functions to infinite argument sequences. For example

(apply concat (repeat '(1 2 3)))

produces a lazy sequence of 1,2,3,1,2,3... Of course for this to work the function also has to be lazy with respect to its argument list.


From the increasingly good ClojureDocs site an idiom using juxt http://clojuredocs.org/clojure_core/clojure.core/juxt

;juxt is useful for forking result data to multiple termination functions
(->> "some text to print and save to a file"
  ((juxt
     println
     (partial  spit "useful information.txt"))))