The is
macro in the clojure.test
namespace can be used to write assertions about the code we want to test. Usually we provide a predicate function as argument to the is
macro. The prediction function will call our code under test and return a boolean value. If the value is true
the assertion passes, if it is false
the assertion fails. But we can also provide a custom assertion function to the is
macro. In the clojure.test
package there are already some customer assertions like thrown?
and instance?
. The assertions are implemented by defining a method for the assert-expr
multimethod that is used by the is
macro. The assert-expr
multimethod is defined in the clojure.test
namespace. In our own code base we can define new methods for the assert-expr
multimethod and provide our own custom assertions. This can be useful to make tests more readable and we can use a language in our tests that is close to the domain or naming we use in our code.
Continue reading →
The clojure.test
namespace has the are
macro that allows us to combine multiple test cases for the code we want to test, without having to write multiple assertions. We can provide multiple values for a function we want to test together with the expected values. Then then macro will expand this to multiple expressions with the is
macro where the real assertion happens. Besides providing the data we must also provide the predicate where we assert our code under test. There is a downside of the are
macro and that is that in case of assertion failures the line numbers in the error message could be off.
Continue reading →
The namespace clojure.pprint
has some useful function to pretty print different data structures. The function print-table
is particularly useful for printing a collection of maps, where each map represents a row in the table, and the keys of the maps represent the column headers. The print-table
function accepts the collection as argument and prints the table to the console (or any writer that is bound to the *out*
var). We can also pass a vector with the keys we want to include in the table. Only the keys we specify are in the output. The order of the keys in the vector we pass as argument is also preserved in the generated output.
Continue reading →
In a previous post we learned how to read text file contents with the slurp
function. To write text file content we use the spit
function. We content is defined in the second argument of the function. The first argument allows several types that will turn into a Writer
object used for writing the content to. For example a string argument is used as URI and if that is not valid as a file name of the file to read. A File
instance can be used directly as argument as well. But also Writer
, BufferedWriter
, OutputStream
, URI
, URL
and Socket
. As an option we can specify the encoding used to write the file content using the :encoding
keyword. The default encoding is UTF-8 if we don’t specify the encoding option. With the option :append
we can define if content needs to be appended to an existing file or the content should overwrite existing content in the file.
Continue reading →
The slurp
funtion in Clojure can be used to read the contents of a file and return it as a string value. We can use several types as argument for the function. For example a string argument is used as URI and if that is not valid as a file name of the file to read. A File
instance can be used directly as argument as well. But also Reader
, BufferedReader
, InputStream
, URI
, URL
, Socket
, byte[]
and char[]
. As an option we can specify the encoding used to read the file content using the :encoding
keyword. The default encoding is UTF-8 if we don’t specify the encoding option.
Continue reading →
The Clojure namespace clojure.java.io
contains useful functions to work with files. One of those functions is make-parents
. We can pass a java.io.File
instance as arguments or use the same arguments that can be passed to the file
function that is also in this namespace. The function will create all parent directories for the file. The return result is true
if the directories are created (they didn’t exist before) and false
when the directories didn’t have to be created (already exist).
In the following example we see an example of usage of the make-parents
function:
Continue reading →
In the clojure.set
namespace we can find the function map-invert
. This function returns a new map where the values are keys with the appropriates keys of the original map assigned as value. If the original map has duplicate values than the latest key for the duplicate value will be the value of the new key.
In the following example code we see the result of using map-invert
:
Continue reading →
Working with Java classes from Clojure code is easy. If we want to invoke methods or access fields on instances of Java classes we must first create an instance by invoking the constructor. In Clojure we can do that using the special form new
or using a dot (.
) notation. The new
special form has the class name of the Java class we want to create an instance of as argument followed by arguments for the Java class constructor. With the dot notation we place a .
after the class name followed by arguments for the class constructor to create a new instance.
In the following example we see several ways to create an instance of a Java class.
Continue reading →
Some of our colleagues at JDriven work with Scala and we talked about the book Functional Programming in Scala written by Paul Chiusano and Runar Bjarnason. We looked at one of the examples in the first chapter in the book to show the importance of having pure functions without side effects. The example is about buying a cup of coffee and charging a credit card with the purchase. In three examples a function with side effects is refactored to a pure function without side effects. When looking at the example I was wondering how this would look like in Clojure using only functions and simple immutable data structures. We can look at the examples in Scala to see how it is explained and implemented in the book. There are also Kotlin samples available. In this post we see a possible implementation in Clojure to buy coffee and charge our credit card.
The first example is a buy-coffee
function with a credit card type as parameter. When we invoke the function with a credit card argument the credit card gets charged as side effect and a coffee type is created and returned. The coffee type is simply a map with a price key.
Continue reading →
In Clojure we can use the merge
function to merge multiple maps into a single map. If a key is in multiple maps the value of the key merged last will be used in the resulting map. If we want to influence how the value of a duplicate key is set we can use merge-with
. We specify as first argument the function that will be used when the same key is available in multiple maps. The function must accept two arguments, where the the first argument is the value of the key in the first map and the second argument the value of the same key in the following map. The result is assigned to the key in the resulting map. If we pass more than two maps to the merge-with
the function will be called multiple times for a key if it is part of more than two maps.
In the following example we use Clojure core functions and a custom function to merge multiples maps, so we can alter the value for duplicate keys:
Continue reading →
Clojure supports advanced destructure features. In a previous post we learned about destructuring maps, but we can also destructure vectors, list and sequences in Clojure using positional destructuring. We can define symbols for positions in the sequence to assign the value at a certain position to the symbol. The first symbol in the destructure vector gets the value of the first element in the sequence, the second symbol the value of the second element and so on. To get the remaining elements from the sequence without assigning them to specific symbols we can use &
followed by a symbol. Then all remaining elements are assigned as sequence the symbol. Finally we can use :as
to get the original vector, list or sequence.
The folowing examples show several destructure definitions for different type of collections and sequences:
Continue reading →
When we want to assign key values in a map to symbols we can use Clojure’s powerful destructure options. With destructuring a map we can use dense syntax to assign keys to new symbols. For example we can use that in a let
special form to assign symbols, but also for function parameters that are a map. When we use it for function parameters we can immediately assign keys to symbols we want to use in the function. Clojure provides a simple syntax to destructure a key value to a symbol using {symbol key}
syntax. The value of :key
will be assigned to symbol
. We can provide default values if a key is not set in the map using :or
followed by the symbol and default value. This is very useful if we know not all keys in a map will have values. Finally there is a shorthand syntax to assign keys to symbols with the same name as the key: :keys
. We must provide a vector to :keys
with the name of the keys, which will automatically assigned to symbols with the same name. To use this destructuring to its fullest the keys in the map must be keywords. We can use the keywordize-keys
function in the clojure.walk
namespace if we have a map with string keys and we want to transform them to keywords.
In the following example code we see several example of map destructuring:
Continue reading →