Syntax and Native Data Types
Let's get our hands dirty with native data types and common operations.
Syntax and native data types#
Clojure affords developers the standard collection of data types. All data structures are immutable. All data structures are manipulated using interfaces. This allows for easy interoperability with the underlying host.
In this module, we'll learn about native data types and some common operations. We suggest that you start the Clojure REPL and try these out for yourself. You can start the REPL using the
Reading Clojure code#
If you don't have a background in LISP, Clojure code will feel unnatural at first. This is because the brackets are in a different position.
In general, when you see a Clojure form like:
In your mind, you should think of it as a list where the first element is an operation to execute and other elements are arguments to that operation. This operation can be a function, a macro, or something else.
type function tells us the native data type of a value or variable. It can be used as follows:
1 can be a variable or any other data type.
Any data type can be
nil. The actual implementation of
nil is dependent on the host. For Clojure, it's Java's
The logical value of
You can determine if a variable is
nil by using the
nil? function. A function suffixed with a question mark
? is conventionally a predicate.
These represent logical
false values. On the JVM these correspond to
false? can be used to ascertain if a value is truthy or falsy.
Like all other data types, numbers are also just the host's implementation of numbers. However, the differences across hosts are ironed out. Leaving the implementation details aside, the following types of numbers are supported.
All numbers in Clojure are
Long by default. You can check this in the REPL by using the
Non-terminating decimals like
22/7 are stored as ratios. The data type for the ratio is
clojure.lang.Ratio. This signifies that
Ratio is a Clojure data type and not dependent on the host.
Clojure takes care of the implementation detail across hosts.
BigInt and BigDecimals#
In case a number is too large for the
Long type, it can be suffixed with an
N to signify
clojure.lang.BigInt. For example
Numbers suffixed with
java.math.BigDecimal or the equivalent host implementation of Java's BigDecimal.
Clojure operations intelligently wrap and transform numbers into the correct data type. For example, if you divide 22 by 7 using the divide
/ function, you'll get a Ratio:
Did you notice how we nested two functions (
Common numerical functions#
Since Clojure has no concept of syntax, numerical operations that you expect from a language are implemented as functions.
For computation, we have
Algebraic functions can take more than one argument:
The core also ships with the functions
dec which add or subtract 1 to a number respectively:
Common comparison functions are also baked into the core. These are
Like arithmetic operators, some comparison operators also take more than one argument:
< function above expects the sequence of arguments to be in increasing order. The same is true for other inequality functions.
Strings are denoted with double quotes "like this".
We already know the
println function. Some other common string functions are:
printlnbut doesn't include a terminating newline
pr-str: Prints the given string and returns it, unlike
prnwhich returns nil
str: Can be used to coerce a value to a string. Can also be used to join multiple strings
string?: Determines if a variable is string or not