Clojure – Destructuring

Clojure – Destructuring ”; Previous Next Destructuring is a functionality within Clojure, which allows one to extract values from a data structure, such as a vector and bind them to symbols without having to explicitly traverse the datastructure. Let’s look at an example of what exactly Destructuring means and how does it happen. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def my-vector [1 2 3 4]) (let [[a b c d] my-vector] (println a b c d))) (Example) The above program produces the following output. Output 1 2 3 4 In the above example, following things are to be noted − We are defining a vector of integers as 1 ,2, 3 and 4. We are then using the ‘let’ statement to assign 4 variables (a, b, c, and d) to the my-vector variable directly. If we run the ‘println’ statement on the four variables, we can see that they have already been assigned to the values in the vector respectively. So clojure has destructured the my-vector variable which has four values when it was assigned using the ‘let’ statement. The deconstructed four values were then assigned to the four parameters accordingly. If there are excess variables which don’t have a corresponding value to which they can be assigned to, then they will be assigned the value of nil. The following example makes this point clear. Example Live Demo (ns clojure.examples.hello (:gen-class)) (defn Example [] (def my-vector [1 2 3 4]) (let [[a b c d e] my-vector] (println a b c d e))) (Example) The above program produces the following output. You can see from the output that since the last variable ‘e’ does not have a corresponding value in the vector, it accounts to nil. Output 1 2 3 4 nil the-rest The ‘the-rest’ variable is used to store the remaining values, which cannot get assigned to any variable. An example on how this is used is shown in the following program. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def my-vector [1 2 3 4]) (let [[a b & the-rest] my-vector] (println a b the-rest))) (Example) The above program produces the following output. From the output, you can clearly see that the values of 3 and 4 cannot be assigned to any variable so they are assigned to the ‘the-rest’ variable. Output 1 2 (3 4) Destructuring Maps Just like vectors, maps can also be destructured. Following is an example of how this can be accomplished. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def my-map {“a” 1 “b” 2}) (let [{a “a” b “b”} my-map] (println a b))) (Example) The above program produces the following output. From the program you can clearly see that the map values of “a” and “b” are assigned to the variables of a and b. Output 1 2 Similarly in the case of vectors, if there is no corresponding value in the map when the destructuring happens, then the variable will be assigned a value of nil. Following is an example. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def my-map {“a” 1 “b” 2}) (let [{a “a” b “b” c “c”} my-map] (println a b c))) (Example) The above program produces the following output. Output 1 2 nil Print Page Previous Next Advertisements ”;

Clojure – Metadata

Clojure – Metadata ”; Previous Next In Clojure, metadata is used to annotate the data in a collection or for the data stored in a symbol. This is normally used to annotate data about types to the underlying compiler, but can also be used for developers. Metadata is not considered as part of the value of the object. At the same time, metadata is immutable. The following operations are possible in Clojure with regards to metadata. Sr.No. Operations & Description 1 meta-with This function is used to define a metadata map for any object. 2 meta This function is used to see if any metadata is associated with an object. 3 vary-meta Returns an object of the same type and value as the original object, but with a combined metadata. Print Page Previous Next Advertisements ”;

Clojure – Concurrent Programming

Clojure – Concurrent Programming ”; Previous Next In Clojure programming most data types are immutable, thus when it comes to concurrent programming, the code using these data types are pretty safe when the code runs on multiple processors. But many a times, there is a requirement to share data, and when it comes to shared data across multiple processors, it becomes necessary to ensure that the state of the data is maintained in terms of integrity when working with multiple processors. This is known as concurrent programming and Clojure provides support for such programming. The software transactional memory system (STM), exposed through dosync, ref, set, alter, etc. supports sharing changing state between threads in a synchronous and coordinated manner. The agent system supports sharing changing state between threads in an asynchronous and independent manner. The atoms system supports sharing changing state between threads in a synchronous and independent manner. Whereas the dynamic var system, exposed through def, binding, etc. supports isolating changing state within threads. Other programming languages also follow the model for concurrent programming. They have a direct reference to the data which can be changed. If shared access is required, the object is locked, the value is changed, and the process continues for the next access to that value. In Clojure there are no locks, but Indirect references to immutable persistent data structures. There are three types of references in Clojure. Vars − Changes are isolated in threads. Refs − Changes are synchronized and coordinated between threads. Agents − Involves asynchronous independent changes between threads. The following operations are possible in Clojure with regards to concurrent programming. Transactions Concurrency in Clojure is based on transactions. References can only be changed within a transaction. Following rules are applied in transactions. All changes are atomic and isolated. Every change to a reference happens in a transaction. No transaction sees the effect made by another transaction. All transactions are placed inside of dosync block. We already seen what the dosync block does, let’s look at it again. dosync Runs the expression (in an implicit do) in a transaction that encompasses expression and any nested calls. Starts a transaction if none is already running on this thread. Any uncaught exception will abort the transaction and flow out of dosync. Following is the syntax. Syntax (dosync expression) Parameters − ‘expression’ is the set of expressions which will come in the dosync block. Return Value − None. Let’s look at an example wherein we try to change the value of a reference variable. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def names (ref [])) (alter names conj “Mark”)) (Example) Output The above program when run gives the following error. Caused by: java.lang.IllegalStateException: No transaction running at clojure.lang.LockingTransaction.getEx(LockingTransaction.java:208) at clojure.lang.Ref.alter(Ref.java:173) at clojure.core$alter.doInvoke(core.clj:1866) at clojure.lang.RestFn.invoke(RestFn.java:443) at clojure.examples.example$Example.invoke(main.clj:5) at clojure.examples.example$eval8.invoke(main.clj:7) at clojure.lang.Compiler.eval(Compiler.java:5424) … 12 more From the error you can clearly see that you cannot change the value of a reference type without first initiating a transaction. In order for the above code to work, we have to place the alter command in a dosync block as done in the following program. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def names (ref [])) (defn change [newname] (dosync (alter names conj newname))) (change “John”) (change “Mark”) (println @names)) (Example) The above program produces the following output. Output [John Mark] Let’s see another example of dosync. Example Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def var1 (ref 10)) (def var2 (ref 20)) (println @var1 @var2) (defn change-value [var1 var2 newvalue] (dosync (alter var1 – newvalue) (alter var2 + newvalue))) (change-value var1 var2 20) (println @var1 @var2)) (Example) In the above example, we have two values which are being changed in a dosync block. If the transaction is successful, both values will change else the whole transaction will fail. The above program produces the following output. Output 10 20 -10 40 Print Page Previous Next Advertisements ”;

Clojure – Discussion

Discuss Clojure ”; Previous Next Clojure is a high level, dynamic functional programming language. It is designed, based on the LISP programming language, and has compilers that makes it possible to be run on both Java and .Net runtime environment. This tutorial is fairly comprehensive and covers various functions involved in Clojure. All the functions are explained using examples for easy understanding. Print Page Previous Next Advertisements ”;

Clojure – Watchers

Clojure – Watchers ”; Previous Next Watchers are functions added to variable types such as atoms and reference variables which get invoked when a value of the variable type changes. For example, if the calling program changes the value of an atom variable, and if a watcher function is attached to the atom variable, the function will be invoked as soon as the value of the atom is changed. The following functions are available in Clojure for Watchers. add-watch Adds a watch function to an agent/atom/var/ref reference. The watch ‘fn’ must be a ‘fn’ of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference”s state might have been changed, any registered watches will have their functions called. Syntax Following is the syntax. (add-watch variable :watcher (fn [key variable-type old-state new-state])) Parameters − ‘variable’ is the name of the atom or reference variable. ‘variable-type’ is the type of variable, either atom or reference variable. ‘old-state & new-state’ are parameters that will automatically hold the old and new value of the variable. ‘key’ must be unique per reference, and can be used to remove the watch with remove-watch. Return Value − None. Example An example on how this is used is shown in the following program. Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def x (atom 0)) (add-watch x :watcher (fn [key atom old-state new-state] (println “The value of the atom has been changed”) (println “old-state” old-state) (println “new-state” new-state))) (reset! x 2)) (Example) Output The above program produces the following output. The value of the atom has been changed old-state 0 new-state 2 remove-watch Removes a watch which has been attached to a reference variable. Syntax Following is the syntax. (remove-watch variable watchname) Parameters − ‘variable’ is the name of the atom or reference variable. ‘watchname’ is the name given to the watch when the watch function is defined. Return Value − None. Example An example on how this is used is shown in the following program. Live Demo (ns clojure.examples.example (:gen-class)) (defn Example [] (def x (atom 0)) (add-watch x :watcher (fn [key atom old-state new-state] (println “The value of the atom has been changed”) (println “old-state” old-state) (println “new-state” new-state))) (reset! x 2) (remove-watch x :watcher) (reset! x 4)) (Example) Output The above program produces the following output. The value of the atom has been changed old-state 0 new-state 2 You can clearly see from the above program that the second reset command does not trigger the watcher since it was removed from the watcher’s list. Print Page Previous Next Advertisements ”;

Clojure – Java Interface

Clojure – Java Interface ”; Previous Next As we already know, Clojure code runs on the Java virtual environment at the end. Thus it only makes sense that Clojure is able to utilize all of the functionalities from Java. In this chapter, let’s discuss the correlation between Clojure and Java. Calling Java Methods Java methods can be called by using the dot notation. An example is strings. Since all strings in Clojure are anyway Java strings, you can call normal Java methods on strings. An example on how this is done is shown in the following program. Example Live Demo (ns Project (:gen-class)) (defn Example [] (println (.toUpperCase “Hello World”))) (Example) The above program produces the following output. You can see from the code that if you just call the dot notation for any string method, it will also work in Clojure. Output HELLO WORLD Calling Java Methods with Parameters You can also call Java methods with parameters. An example on how this is done is shown in the following program. Example Live Demo (ns Project (:gen-class)) (defn Example [] (println (.indexOf “Hello World”,”e”))) (Example) The above program produces the following output. You can see from the above code, that we are passing the parameter “e” to the indexOf method. The above program produces the following output. Output 1 Creating Java Objects Objects can be created in Clojure by using the ‘new’ keyword similar to what is done in Java. An example on how this is done is shown in the following program. Example Live Demo (ns Project (:gen-class)) (defn Example [] (def str1 (new String “Hello”)) (println str1)) (Example) The above program produces the following output. You can see from the above code, that we can use the ‘new’ keyword to create a new object from the existing String class from Java. We can pass the value while creating the object, just like we do in Java. The above program produces the following output. Output Hello Following is another example which shows how we can create an object of the Integer class and use them in the normal Clojure commands. Example Live Demo (ns Project (:gen-class)) (defn Example [] (def my-int(new Integer 1)) (println (+ 2 my-int))) (Example) The above program produces the following output. Output 3 Import Command We can also use the import command to include Java libraries in the namespace so that the classes and methods can be accessed easily. The following example shows how we can use the import command. In the example we are using the import command to import the classes from the java.util.stack library. We can then use the push and pop method of the stack class as they are. Example Live Demo (ns Project (:gen-class)) (import java.util.Stack) (defn Example [] (let [stack (Stack.)] (.push stack “First Element”) (.push stack “Second Element”) (println (first stack)))) (Example) The above program produces the following output. Output First Element Running Code Using the Java Command Clojure code can be run using the Java command. Following is the syntax of how this can be done. java -jar clojure-1.2.0.jar -i main.clj You have to mention the Clojure jar file, so that all Clojure-based classes will be loaded in the JVM. The ‘main.clj’ file is the Clojure code file which needs to be executed. Java Built-in Functions Clojure can use many of the built-in functions of Java. Some of them are − Math PI function − Clojure can use the Math method to the value of PI. Following is an example code. Example Live Demo (ns Project (:gen-class)) (defn Example [] (println (. Math PI))) (Example) The above code produces the following output. Output 3.141592653589793 System Properties − Clojure can also query the system properties. Following is an example code. Example Live Demo (ns Project (:gen-class)) (defn Example [] (println (.. System getProperties (get “java.version”)))) (Example) Depending on the version of Java on the system, the corresponding value will be displayed. Following is an example output. Output 1.8.0_45 Print Page Previous Next Advertisements ”;

Clojure – Sequences

Clojure – Sequences ”; Previous Next Sequences are created with the help of the ‘seq’ command. Following is a simple example of a sequence creation. Live Demo (ns clojure.examples.example (:gen-class)) ;; This program displays Hello World (defn Example [] (println (seq [1 2 3]))) (Example) The above program produces the following output. (1 2 3) Following are the various methods available for sequences. Sr.No. Methods & Description 1 cons Returns a new sequence where ‘x’ is the first element and ‘seq’ is the rest. 2 conj Returns a new sequence where ‘x’ is the element that is added to the end of the sequence. 3 concat This is used to concat two sequences together. 4 distinct Used to only ensure that distinct elements are added to the sequence. 5 reverse Reverses the elements in the sequence. 6 first Returns the first element of the sequence. 7 last Returns the last element of the sequence. 8 rest Returns the entire sequence except for the first element. 9 sort Returns a sorted sequence of elements. 10 drop Drops elements from a sequence based on the number of elements, which needs to be removed. 11 take-last Takes the last list of elements from the sequence. 12 take Takes the first list of elements from the sequence. 13 split-at Splits the sequence of items into two parts. A location is specified at which the split should happen. Print Page Previous Next Advertisements ”;

Clojure – File I/O

Clojure – File I/O ”; Previous Next Clojure provides a number of helper methods when working with I/O. It offers easier classes to provide the following functionalities for files. Reading files Writing to files Seeing whether a file is a file or directory Let’s explore some of the file operations Clojure has to offer. Reading the Contents of a File as an Entire String If you want to get the entire contents of the file as a string, you can use the clojure.core.slurp method. The slurp command opens a reader on a file and reads all its contents, returning a string. Following is an example of how this can be done. (ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (def string1 (slurp “Example.txt”)) (println string1)) (Example) If the file contains the following lines, they will be printed as − line : Example1 line : Example2 Reading the Contents of a File One Line at a Time If you want to get the entire contents of the file as a string one line at a time, you can use the clojure.java.io/reader method. The clojure.java.io/reader class creates a reader buffer, which is used to read each line of the file. Following is an example that shows how this can be done. (ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (with-open [rdr (clojure.java.io/reader “Example.txt”)] (reduce conj [] (line-seq rdr)))) (Example) If the file contains the following lines, they will be printed as − line : Example1 line : Example2 The output will be shown as − [“line : Example1” “line : Example2”] Writing ‘to’ Files If you want to write ‘to’ files, you can use the clojure.core.spit command to spew entire strings into files. The spit command is the opposite of the slurp method. This method opens a file as a writer, writes content, then closes file. Following is an example. (ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (spit “Example.txt” “This is a string”)) In the above example, if you see the contents of the Example.txt file , you will see the contents of “This is a string”. Writing ‘to’ Files One Line at a Time If you want to write ‘to’ files one line at a time, you can use the clojure.java.io.writer class. The clojure.java.io.writer class is used to create a writer stream wherein bytes of data are fed into the stream and subsequently into the file. Following is an example that shows how the spit command can be used. (ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (with-open [w (clojure.java.io/writer “Example.txt” :append true)] (.write w (str “hello” “world”)))) (Example) When the above code is executed, the line “hello world” will be present in the Example.txt file. The append:true option is to append data to the file. If this option is not specified, then the file will be overwritten whenever data is written to the file. Checking to See If a File Exists To check if a file exists, the clojure.java.io.file class can be used to check for the existence of a file. Following is an example that shows how this can be accomplished. (ns clojure.examples.hello (:gen-class)) ;; This program displays Hello World (defn Example [] (println (.exists (clojure.java.io/file “Example.txt”)))) (Example) If the file Example.txt exists, the output will be true. Reading from the Console To read data from the console, the read-line statement can be used. Following is an example that shows how this can be used. If you enter the (read-line) command in the REPL window, you will have the chance to enter some input in the console window. user->(read-line) Hello World The above code will produce the following output. “Hello World” Print Page Previous Next Advertisements ”;

Clojure – Reference Values

Clojure – Reference Values ”; Previous Next Reference values are another way Clojure can work with the demand to have mutable variables. Clojure provides mutable data types such as atoms, agents, and reference types. Following are the operations available for reference values. Sr.No. Operations & Description 1 ref This is used to create a reference value. When creating a reference value, there is an option to provide a validator function, which will validate the value created. 2 ref-set This function is used to set the value of a reference to a new value irrespective of whatever is the older value. 3 alter This function is used to alter the value of a reference type but in a safe manner. This is run in a thread, which cannot be accessed by another process. 4 dosync Runs the expression (in an implicit do) in a transaction that encompasses expression and any nested calls. 5 commute Commute is also used to change the value of a reference type just like alter and ref-set. Print Page Previous Next Advertisements ”;

Clojure – Maps

Clojure – Maps ”; Previous Next A Map is a collection that maps keys to values. Two different map types are provided – hashed and sorted. HashMaps require keys that correctly support hashCode and equals. SortedMaps require keys that implement Comparable, or an instance of Comparator. A map can be created in two ways, the first is via the hash-map method. Creation – HashMaps HashMaps have a typical key value relationship and is created by using hash-map function. Live Demo (ns clojure.examples.example (:gen-class)) (defn example [] (def demokeys (hash-map “z” “1” “b” “2” “a” “3”)) (println demokeys)) (example) Output The above code produces the following output. {z 1, b 2, a 3} Creation – SortedMaps SortedMaps have the unique characteristic of sorting their elements based on the key element. Following is an example that shows how the sorted map can be created using the sorted-map function. Live Demo (ns clojure.examples.example (:gen-class)) (defn example [] (def demokeys (sorted-map “z” “1” “b” “2” “a” “3”)) (println demokeys)) (example) The above code produces the following output. {a 3, b 2, z 1} From the above program you can clearly see that elements in the maps are sorted as per the key value. Following are the methods available for maps. Sr.No. Maps & Description 1 get Returns the value mapped to key, not-found or nil if key is not present. 2 contains? See whether the map contains a required key. 3 find Returns the map entry for the key. 4 keys Returns the list of keys in the map. 5 vals Returns the list of values in the map. 6 dissoc Dissociates a key value entry from the map. 7 merge Merges two maps entries into one single map entry. 8 merge-with Returns a map that consists of the rest of the maps conj-ed onto the first. 9 select-keys Returns a map containing only those entries in map whose key is in keys. 10 rename-keys Renames keys in the current HashMap to the newly defined ones. 11 map-invert Inverts the maps so that the values become the keys and vice versa. Print Page Previous Next Advertisements ”;