understanding core clojure functions...if val is supplied, returns the result of applying f to val...
TRANSCRIPT
![Page 1: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/1.jpg)
Understanding Core Clojure Functions
Dr. Jonathan Graham
http://jonathangraham.github.io twitter: @graham_jp
8th Light
![Page 2: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/2.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 3: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/3.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 4: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/4.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 5: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/5.jpg)
Are you fully in control when you code?
http://jonathangraham.github.io twitter: @graham_jp
![Page 6: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/6.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 7: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/7.jpg)
If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that
result and the 2nd item, etc.
If coll contains no items, returns val and f is not called.
http://jonathangraham.github.io twitter: @graham_jp
![Page 8: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/8.jpg)
Let’s start with a test…
http://jonathangraham.github.io twitter: @graham_jp
![Page 9: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/9.jpg)
A second test could have a single element in the collection.
http://jonathangraham.github.io twitter: @graham_jp
![Page 10: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/10.jpg)
With more than one item in the collection…
We can add tests with different functions, collections and initial values.
http://jonathangraham.github.io twitter: @graham_jp
![Page 11: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/11.jpg)
If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that
result and the 3rd item, etc.
http://jonathangraham.github.io twitter: @graham_jp
![Page 12: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/12.jpg)
No val…
We can add tests with multiple items in coll.
http://jonathangraham.github.io twitter: @graham_jp
![Page 13: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/13.jpg)
If coll contains no items, f must accept no arguments as well, and reduce returns the result of
calling f with no arguments.
http://jonathangraham.github.io twitter: @graham_jp
![Page 14: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/14.jpg)
No val and empty coll…
http://jonathangraham.github.io twitter: @graham_jp
![Page 15: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/15.jpg)
How many unit tests are enough to give us confidence that our function behaves in the same
was as reduce?
http://jonathangraham.github.io twitter: @graham_jp
![Page 16: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/16.jpg)
Property-based tests
Make statements about the expected behaviour of the code that should hold true for the entire domain of possible
inputs. These statements are then verified for many different (pseudo)randomly generated inputs.
http://jonathangraham.github.io twitter: @graham_jp
Clojure test.check
![Page 17: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/17.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 18: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/18.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 19: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/19.jpg)
Functions requiring two arguments can be passed to reduce with only a single argument
(defn f [x y] (+ x y))
(reduce f [1])
http://jonathangraham.github.io twitter: @graham_jp
![Page 20: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/20.jpg)
Care needed with functions that cannot be evaluated with no arguments
(reduce - ‘())
http://jonathangraham.github.io twitter: @graham_jp
![Page 21: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/21.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 22: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/22.jpg)
Taking a TDD approach again…
http://jonathangraham.github.io twitter: @graham_jp
![Page 23: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/23.jpg)
Make tests with more than one element pass
http://jonathangraham.github.io twitter: @graham_jp
![Page 24: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/24.jpg)
With a passing test suite, refactor
http://jonathangraham.github.io twitter: @graham_jp
![Page 25: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/25.jpg)
Again, property-based tests can confirm that our function behaves the same as the core function
http://jonathangraham.github.io twitter: @graham_jp
![Page 26: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/26.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 27: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/27.jpg)
Filter returns a lazy sequence
http://jonathangraham.github.io twitter: @graham_jp
![Page 28: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/28.jpg)
Build function up recursively?
http://jonathangraham.github.io twitter: @graham_jp
![Page 29: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/29.jpg)
We can add more tests, and these pass
http://jonathangraham.github.io twitter: @graham_jp
But, our function is not lazy!
We just convert the result to a lazy sequence
![Page 30: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/30.jpg)
cons is lazy; conj is not
http://jonathangraham.github.io twitter: @graham_jp
conj depends on the collection type, so is realised immediately
cons adds an item to the start of a collection, and can be evaluated lazily
![Page 31: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/31.jpg)
Refactor lazily
http://jonathangraham.github.io twitter: @graham_jp
![Page 32: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/32.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 33: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/33.jpg)
How do we get a vector containing just the even numbers given an input of [0 1 2 3 4 5]?
http://jonathangraham.github.io twitter: @graham_jp
![Page 34: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/34.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 35: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/35.jpg)
For a single collection, write our map function analogously to our filter function
http://jonathangraham.github.io twitter: @graham_jp
![Page 36: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/36.jpg)
We can extend this approach for two collections
http://jonathangraham.github.io twitter: @graham_jp
![Page 37: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/37.jpg)
What about more than two collections? Build up recursively?
http://jonathangraham.github.io twitter: @graham_jp
![Page 38: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/38.jpg)
Does this work for non-commutative functions?
http://jonathangraham.github.io twitter: @graham_jp
![Page 39: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/39.jpg)
How can build lazily?
http://jonathangraham.github.io twitter: @graham_jp
1) Take all of the input collections, and put them into a single sequence.
2) Reorder this sequence, so the first collection is all of the first elements, the second collection is all of the second elements, etc.
3) Map the result of applying the function to each reordered collection in turn
![Page 40: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/40.jpg)
Our map function
http://jonathangraham.github.io twitter: @graham_jp
![Page 41: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/41.jpg)
Our map function
http://jonathangraham.github.io twitter: @graham_jp
![Page 42: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/42.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 43: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/43.jpg)
map is lazy, and the time we are measuring is the time to make a new lazy-seq, not the time to actually execute it
http://jonathangraham.github.io twitter: @graham_jp
![Page 44: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/44.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 45: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/45.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 46: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/46.jpg)
Fails
http://jonathangraham.github.io twitter: @graham_jp
![Page 47: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/47.jpg)
We need to generate all of the futures before we start to deref
Remember that conj is not lazy…
http://jonathangraham.github.io twitter: @graham_jp
![Page 48: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/48.jpg)
Extend to multiple collections as we did with my-map
http://jonathangraham.github.io twitter: @graham_jp
![Page 49: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/49.jpg)
The behavior of all the functions can be confirmed to be the same as the core functions using
property-based tests
http://jonathangraham.github.io twitter: @graham_jp
![Page 50: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/50.jpg)
http://jonathangraham.github.io twitter: @graham_jp
![Page 51: Understanding Core Clojure Functions...If val is supplied, returns the result of applying f to val and the first item in coll, then applying f to that result and the 2nd item, etc](https://reader033.vdocuments.us/reader033/viewer/2022060900/609dc96196605a0dc428fb82/html5/thumbnails/51.jpg)
Understanding Core Clojure Functions
Dr. Jonathan Graham
http://jonathangraham.github.io twitter: @graham_jp
8th Light