Strings are one of the most intrinsic things that we use to communicate. This book is essentially being parsed in your mind as a series of strings. Strings are often objects of input/output in programs to be modified, displayed, and fudged with. Lets look at some example strings in Clojure:
(str "Are you wearing pants?") ;=>"Are you wearing pants?") ("Are you wearing pants?") ;=>"Are you wearing pants
As you can see, if using the str method you will just get the original string returned if you are not concatenating anything, as we did earlier.
If you're familiar with a variety of languages you probably are of the understanding that depending on what you are working with, a string can be both an object or a primitive. In Ruby, we could define a string as follows:
this = String.new("I'm not wearing pants")
this = "I'm not wearing pants"
pants = "a thing you should not wear when relaxing at home"
String("Man, I sure hate wearing pants") =>"Man, I sure hate wearing pants"
In Clojure, though it is a representation of a string object in Java, it is not a string object in the sense of how we will utilize it and investigate its properties as well as compare them to others.
(=("I just took off my pants")(str ("I just took off my ")("pants)) ;=>true
In Clojure, we aren't functioning in an Object Oriented language. It is primarily functional in its application.
Though Clojure itself is not an object oriented language, it is, however, implemented in Java. The compilation results in the code being run as Java VM code. This results in a string in Clojure being compiled as an instance of a String object in Java, which is a series of char primitives.
Most of Clojure's data types are immutable, as mentioned prior. They never change. Clojure favors comparison of equality much moreso than comparison of identity. In most languages this is discouraged because the values are deeply built into the structure of each instance of an object. Thusly, Clojure compares content. An example:
(= "pants" ( str "pan" "ts")) ;=>true
However, in Ruby:
class Foo end
Now that we have defined a class, lets make some instances of it
a = Foo.new() b = Foo.new() a == b >false
Clojure makes this comparison cheap on resources. A Clojure object in this situation is keeping around a hash of itself, and this hash is what is compared rather than deeply inspecting it. This, however, only works if all parties involved are completely immutable. As stated, not ALL pieces of Clojure are immutable.
As with many other languages, strings in Clojure have many built in methods. Here are some examples:
The str method will simply return an empty string if there are no other list items.
(string? "x") ;=>true
This operator will determine if a given item is a string. However, it cannot handle multiple arguments.
(string? "x" 1) ;=>clojure.lang.ArityException: Wrong number of args (2) passed to: core$string-QMARK-
Clojure's way of recognizing regular expressions is the '#' operator. The
re-find and re-match are the functions Clojure uses for its matches.
(re-find #"I don't have pants on" "Man I am sure glad I don't have pants on") ;=>"I don't have pants on (re-find #"pants" "I do not adorm my lower half with garments!") ;=>nil (rest (re-matches #"(.+)fun(.+)" "Its all fun and games until someone gets hurt")) ;=>hahahah it looks like a penis
The last version does a more standardized regex rather than a simple text search. These will be examined further later when working with web applications where they are quite useful for formatting and validation. For now simply know that "rest" returns the rest of the string after the match is found.
There is also capitalize and trim-newline (akin to chomp) methods just like Ruby. They perform as expected (capitalize the first letter of a word, and remove a trailing newline, respectively). For an in depth listing of String methods in Clojure check out the documentation.
There are no exercises for this chapter. Just meditate on what a string is when it is not truly an object. The key of this exercise is the differentiation between the typical OO class model vs allowing rote comparison of contents as Clojure does. This will be just the beginning of our new way of "thinking in Clojure".