Next: exploring-clojure
In java, compare how to add an isBlank
function to a
String
:
public class StringUtils {
public static boolean isBlank(final CharSequence str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(str.charAt(i)) == false) {
return false;
}
}
return true;
}
}
This requires you to create a new class, a static method (in java, there are no such thing as free functions, so you have to create a static method, and you can’t open the string namespace, so you have to create a new one.
Meanwhile, the clojure one is simple:
defn blank? [str]
(every? #(Character/isWhitespace %) str)) (
Compare defining a simple Person class in Java:
public class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
to Clojure:
defrecord Person [first-name last-name])
(
def foo(->Person "Aaron" "Bedra"))
(-> #'user/foo
:first-name foo)
(-> Aaron
Clojure data is immutable (it uses persistent data structures), so
hashCode()
and equals()
are automatically
derived for you:
Clojure is extendable with macros – you can redefine keywords at will, for many use cases. In fact, most keywords are just macros, like defrecord:
You can even extend defrecord
easily, if you’d like to
apply strong typing and disallow nils.
defrecord name [Type :arg1 Type :arg2 Type :arg3]
(:allow-nils false)
Clojure has a few improvements over traditional lisps:
seq
(Sequence),
kind of like an iterable in other languages, which you can define for
your own types.1,2,3,4] # valid vector
[1 2 3 4 ] # also valid [
; Common Lisp cond
(cond ((= x 10) "equal")
((> x 10) "more"))
; Clojure cond
cond (= x 10) "equal"
(> x 10) "more") (
For example, here’s a list comprehension of all composers who have written a composition named “Requiem”:
(for [c compositions :when (= (:name c) “Requiem”)] (:composer c)) -> (“W. A. Mozart” “Giuseppe Verdi”)
This has a few desirable properties:
Clojure’s functional programming and immutability make it easy to write thread-safe code:
Next: exploring-clojure