2020-06-27 Clojure 3

3 minute read

More Clojure

Welcome back again. Last time we ended with assoc and dissoc. Tonight we will start with Sets.

NOTE:

I am writing this as a way to digest and understand the book that I am working through entitled. Living Clojure

Sets

What is a set? Sets are collections without duplicates and can be denoted with #{} Because of the nature of the set, we get a few extra methods to use on them, union difference and intersection. This can be accessed by doing a prefix of clojure.set Lets take a look at simply creating some sets.

user=> #{:one :two :three}
#{:one :three :two}
user=> #{:one :two :two :three}
Syntax error reading source at (REPL:2:25).
Duplicate key: :two

user=> #{"one" "two" "three"}
#{"three" "two" "one"}
user=> #{"one" "two" "two" "three"}
Syntax error reading source at (REPL:3:29).
Duplicate key: two
user=>

Simple enough right? Alright lets see about using some of those methods I mentioned. Something to keep in mind, if we are using the basic REPL then we are going to need to require and load in the library before we can use it.

user=> (require '[clojure.set])
nil
user=> (clojure.set/union #{1 2 3} #{2 3 4})
#{1 4 3 2}
user=>

The union is going to merge set1 and set2 and give us back a set of all the unique keys.

user=> (require '[clojure.set])
nil
user=> (clojure.set/difference #{1 2 3} #{2 3 4})
#{1}
user=>

The difference method when passed set1 and set2 is going to give the values that are not a part of set2, that exist in set1 This can be visualized much like “subtraction” in math land.

user=> (require '[clojure.set])
nil
[Auser=(clojure.set/intersection #{1 2 3} #{2 3 4})
#{3 2}
user=>

The intersection method is going to return the values that are present in both sets.
If we would like to use these methods on things that are not sets, then we can convert other things in to sets pretty easily. First lets take a vector and turn it in to a set and then do things to it.

user=> (require '[clojure.set])
nil
user=> (clojure.set/union (set [1 2 3 ]) (set [2 3 4 5 ])))
#{1 4 3 2 5}

What about getting something out of a set? We can do that with a get, if the element is a keyword. There is also some nice things that we can do like includes to get boolean information back out.

user=> (get #{:one :two :three} :three)
:three

user=> (get #{:one :two :three} :four)
nil

user=> (:onet #{:one :two :three})
nil

user=> (:one #{:one :two :three})
:one

user=> ( #{:one :two :three}:two)
:two

user=>
user=> ( contains? #{:one :two :three} :two)
true

Alright that is going to wrap up this round because with that I am done with the basic data structures in clojure.

Extra bite

When I was looking around for a good explanation about what functional programming is I came across a good side by side explanation of it. Lets take a look. wikipedia functional programming …multiply all even numbers in an array by 10 and add them all, storing the final sum in the variable “result”. Traditional Imperative Loop:

const numList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let result = 0;
for (let i = 0; i < numList.length; i++) {
  if (numList[i] % 2 === 0) {
    result += (numList[i] * 10)
  }
}

Functional Programming with higher-order functions:

const numList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const result = numList
               .filter(n => n % 2 === 0)
               .map(a => a * 10)
               .reduce((a, b) => a + b)

Categories:

Updated: