start content of chapter 3

rhgraysonii authored
revision 07abead948567ea6165fd4976fd701a328d8b514
# More Types

## Symbols
Let's look at a symbol.

(class 'str)

A symbol in Clojure is a piece that allows us to reference things locally. For our purposes there is not much more that is needed in digging into them.Their most common use is to be referred to then filled in with a value.

## Booleans
If you are familiar with program concepts in general (which you should be if reading this book) you will have heard the term 'truthiness' many times before. The 'truthiness' structure of Clojure works as follows.

(boolean false)

(boolean true)

(boolean nil)

As you can see, there is little surprise here outside of nil returning false. In Ruby we would see this:


So, we now can deduce nil evaluates to false. Now, let us look at the next thing that may catch you off guard if you come from the wonderful land of C.

(boolean 0)
;=> true

Clojure's only negative return types are nil and false. Now, we can also use our standard not, and, and or operators.

(not "pants")
;=> false;

(not nil)

Not returns the opposite.

(and "pants" "are" "off")

(and false true true false)

And returns the first negative value, or the last one if all are truthy.

(or false "my pants are off")
;=>"my pants are off"

Or returns the first positive value.

## Keywords
Keywords are much like symbols. They contain a value to name something. They are much more useful when being paired with other data rather than operating on their lonesome. (They are just SO clingy)


We'll play with these rascals more once we get into maps later.

## Lists
Lists are the most integral building block of any lisp.

'("my pants are off" 9999 "hashtag coding")
;=>("my pants are off" 9999 "hashtag coding")

We also can use the keyword 'list'. It is your call.

(list "my" "pants" "are" "missing")
;=>("my" "pants" "are" "missing")

We can compare lists. It happens as you may expect.

(= '("my pants are off")("my pants are off"))

We can add to them using the conjoin command, as well.

(conj '("pants" "are off") "my")
;=>("my" "pants" "are off")

Much like in other languages, we can call first on a list.

(first ("dance" "sing" "eat" "sleep" "die")

We can also call any element we know the number of arbitrarily with the "nth" operator.

(nth ( 1 2 3 4 5 6 ) 3)

Note that indexing works in the standard way you should be used to.

## Vectors
Now, I feel like you might just be a *little* sick of parentheses. So lets check some square brackets out (trust me, they go hard in the paint too)

["my pants" "are off"]
;=>["my pants" "are off"]

Vectors don't need parentheses because they are evaluated in a different way than lists. We also can turn other things into vectors (just like we can with strings using our str command) or conjoin to them.

(vec ("definitely not wearing" "pants"))
;=>["definitely not wearing" "pants"]

(conj [1 2 3 4] "tell me that you love me more")
;=>[1 2 3 4 "tell me that you love me more"]

Note that the conjoin command adds to the end of the vector, rather than the beginning as it does if it is a list. We also have the same first and nth operators. We also have two new ones called next and rest though.

(rest ["no, I have" "no" "pants" "on"])
;=>["no" "pants" "on"]

(next ["sure glad" "I dont" "have pants on"])
;=>["I dont" "have pants on"]

The only difference between them is how they operate when evaluating an empty vector. Next will return nil and rest will return an empty list.
Other standard methods such as count and last. We also can look things up by index quite simply.

(["Harry Potter" "Ron Weasley" "Hermoine Granger"] 0)
;=>"Harry Potter"

Now, remember earlier when we described equality in Clojure? Each of these items contains a hash that tells what is inside of it. So now if we take a vector and a list to be compared, let us examine the output.

(= [1 2 3] (1 2 3)]

## Sets
Sets are collections of values that are totally unordered. They never contain duplicate elements, and calling a set will not always output the order the same as when you made it. A set is denoted in the following way.

#{1 2 3 4}
;=>#{2 1 3 4}

We can use all of our standard methods such as conj, first, last, nth, etc. here as well. We also can introduce the disjoin method.

(disj #{1 2 3 4} 1)
;=>#{2 4 3}

One of the most common operations on sets is 'contains?'.

(contains? #{:im :not :wearing :pants} :pants)

We can set other things as sets too using the 'set' operator.

(set ["your pants" "on the floor"])
;=>#{"your pants" "on the floor"}

## Maps
Maps bring a concept we all know and love. Key value pairs! They contain both mad swag, and one element called a 'key' linked to a 'value', as you may have already guessed. Lets look at some.

{:pants "off" :sports "on" :pizza "frozen"}
;=>{:sports "on" :pants "off" :pizza "frozen"}

We can 'get' a value looking up a key.

(get {:no "pants" :pants "off"} :pants)

If the element does not exist, nil will be returned. We can also use a key or value directly as a verb to do a lookup like this.

({"pants" "none" "shoes" "fly"} "pants")

(:pants {:pants "off" :game "on"})

You can also add or replace a key using the assoc command. If it already exists it will be overwritten.

(assoc {"pants location" "legs"} "pants location" "floor")
;=>{"pants location" "floor"}

The dissoc command does exactly the opposite, it removes a value.

(dissoc {:pants "none" :shirt "on"} :shirt)
;=>{:pants "none"}

You can also merge maps. The later values overwrite the first ones if there is repetition resulting in overlap.

(merge {:pants "off" :wings "cookin"} {:game "on" :wings "served"})
;=>{:pants "off" :wings "done" :game "on}

Now, as a hacker of sorts I'm sure you generally think about how you could use these things to represent real world data. Knowing the minor details and quirks of all of them now, take some time and just think of the possibilities and play in the REPL. Next in our world comes the wonderful world of functions.