The Marvelous Land of Higher Order Functions

111
The Marvelous Land of Higher Order Functions Mike Harris

Transcript of The Marvelous Land of Higher Order Functions

The Marvelous Land of Higher Order Functions Mike Harris

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

Know thyself γνῶθι σεαυτόν

Croesus King of Lydia (560 - 547 BC)

–- Herodotus, The Histories

“[I]f Croesus attacked the Persians, he would destroy a mighty empire”

Cyrus the Great founder of the Achaemenid Empire

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

–- L. Frank Baum, The Marvelous Land of Oz

“Everything in life is unusual until you get accustomed to it.”

f g

f(g)

Function

f

g

Function

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

Reduce• Reduce (Clojure, Underscore.js)

• Aggregate (C#)

• Fold (Haskell)

• Accumulate (C++)

Reducer

Collection

Result

1 2 3 4

Add

10

var sum = 0;!var arr =! new[] {1, 2, 3, 4};!foreach(var x in arr)!{! sum += x;!}!!

// 10

new[] {1, 2, 3, 4}!.Aggregate(! 0,!!(m, x) => m += x); !!

// 10

(reduce!!! #(+ %1 %2) !!!![1 2 3 4])!!

;; 10

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

Map• Map (Clojure, Haskell, Underscore.js)

• Select (C#)

• Transform (C++)

Mapper

Collection

Result

1 2 3 4

Increment

2 3 4 5

new[] {1, 2, 3, 4}!.Select(x => x+1); !!

// { 2, 3, 4, 5 }

(map inc [1 2 3 4])!!

;; [2 3 4 5]

(map inc [1 2 3 4])!!

;; [2 3 4 5]

reduce

map

add to

collectionfunction

new[] {1, 2, 3, 4}!.Aggregate(! new List<int>(),! (m, x) => {! m.Add(x+1);! return m;! }).ToArray();!!

// { 2, 3, 4, 5 }

new[] {1, 2, 3, 4}!.Aggregate(! new int[]{},! (m, x) => m.Add(x+1)); !!

// { 2, 3, 4, 5 }

FAKE C# CODE!!!

FAKE C# CODE!!!

new[] {1, 2, 3, 4}!.Select(x => x+1); !!

// { 2, 3, 4, 5 }

(reduce!!! #(conj %1 (inc %2))! [] !!!![1 2 3 4])!!

;; [2 3 4 5]

(map! inc! [1 2 3 4])!!

;; [2 3 4 5]

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

Filter• Filter (Clojure, Haskell, Underscore.js)

• Where (C#)

• Remove (C++)

Filter

Collection

Result

1 2 3 4

Odd?

1 3

new[] {1, 2, 3, 4}!.Where(x => x%2 != 0);!!

// { 1, 3 }

(filter odd? [1 2 3 4])!!

;; [1 3]

reduce

filter

add to

collectionpredicate

new[] {1, 2, 3, 4}!.Aggregate(! new List<int>(),! (m, x) => {! if (x%2 != 0)! m.Add(x);! return m;!}).ToArray();!// { 1, 3 }

new[] {1, 2, 3, 4}!.Aggregate(! new int[]{},! (m, x) => ! (x%2 != 0)! ? m.Add(x+1) : m); !// { 1, 3 }

FAKE C# CODE!!!

FAKE C# CODE!!!

new[] {1, 2, 3, 4}!.Where(x => x%2 != 0);!!

// { 1, 3 }

(reduce ! #(if (odd? %2)! (conj %1 %2)! %1)! [] ! [1 2 3 4])!!

;; [1 3]

(filter! odd?! [1 2 3 4])!!

;; [1 3]

FizzBuzz

Kata

1 2 Fizz 4 Buzz Fizz 7 8 Fizz

Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz

Enumerable.Range(1, 35)! .Select(x => {! if (x%15 == 0) return “FizzBuzz”;! if (x%3 == 0) return “Fizz”;! if (x%5 == 0) return “Buzz”;! return x.ToString();!});! !// { “1”, “2”, “Fizz”, “4”, “Buzz”

Enumerable.Range(1, 35)! .Aggregate(! new List<string>(), ! (m, x) => {! if (x%15==0) m.Add(“FizzBuzz”);! else if (x%3==0) m.Add(“Fizz”);! else if (x%5==0) m.Add(“Buzz”);! else m.Add(x.ToString());! return m;!});! !// { “1”, “2”, “Fizz”, “4”, “Buzz”

Coin Changer

Kata

Func<int[], int, int[]> changer = !(coins, amount) => coins.Select(! coin => { ! var c = amount / coin; ! amount %= coin; ! return c;! }).ToArray();!!

changer(new[] {25,10,5,1}, 99);!!

// { 3, 2, 0, 4 }

Func<int[], int, int[]> changer = !(coins, amount) => coins.Aggregate(! new List<int>(),! (m, coin) => {! m.Add(amount / coin); ! amount %= coin; ! return m;! }).ToArray();!!

changer(new[] {25,10,5,1}, 99);!!

// { 3, 2, 0, 4 }

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

–- L. Frank Baum, The Emerald City of Oz

“[I]t is folly for us to try to appear otherwise than as nature has made us.”

Mapcat• Mapcat (Clojure)

• SelectMany (C#*)

• >>= (Haskell*)

* not exactly the same as Clojure’s mapcat

MapperCatter

Collection

Result

1 2 3 4

Identity

2 3 4 20

20 10

101

new[] {! new[] {1, 2, 3, 4},! new[] {20, 10}!}.SelectMany(x => x);!!

// { 1, 2, 3, 4, 20, 10 }

(mapcat identity ! [[1 2 3 4] [20 10]])!!

;; [1 2 3 4 20 10]

1 2 3 4

Increment

3 4 5 21

20 10

112

new[] {! new[] {1, 2, 3, 4},! new[] {20, 10}!}.SelectMany(! x => x.Select(! y => y+1));!!

// { 2, 3, 4, 5, 21, 11 }

new[] {! new[] {1, 2, 3, 4},! new[] {20, 10}!}.SelectMany(x => x)!.Select(x => x + 1);!!

// { 2, 3, 4, 5, 21, 11 }

(mapcat! #(map inc %) ! [[1 2 3 4] [20 10]])!!

;; [2 3 4 5 21 11]

(map inc! (mapcat identity! [[1 2 3 4] [20 10]])!)!!

;; [2 3 4 5 21 11]

(->>! [[1 2 3 4] [20 10]]! (mapcat identity)! (map inc))!!

;; [2 3 4 5 21 11]

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

–- L. Frank Baum, The Wonderful Wizard of Oz

“Even with eyes protected by the green spectacles, Dorothy and her friends were at first dazzled by the brilliancy of the wonderful

City.”

Zip• Map (Clojure)

• Zip (C#)

• ZipWith (Haskell)

Zipper

Collection Collection

Result

1 2 3

Add

10 20 30

11 22 33

new[] {1, 2, 3}!.Zip(! new[] {10, 20, 30},! (x, y) => x + y);!!

// { 11, 22, 33 }

(map + ! [1 2 3] [10 20 30])!!

;; [11 22 33]

1 2

Add

10 20 30

11 22 ???

new[] {1, 2}!.Zip(! new[] {10, 20, 30},! (x, y) => x + y);!!

// { 11, 22 }

(map + ! [1 2] [10 20 30])!!

;; [11 22]

1 2 3

Add

10 20

11 22 ???

new[] {1, 2, 3}!.Zip(! new[] {10, 20},! (x, y) => x + y);!!

// { 11, 22 }

(map + ! [1 2 3] [10 20])!!

;; [11 22]

FizzBuzz

Kata

1 2 Fizz 4 Buzz Fizz 7 8 Fizz

Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz

var inf = Enumerable.Range(0, int.MaxValue);!var fizzes = inf.Select(x => x%3 == 0 ? “Fizz” : “”);!var buzzes = inf.Select(x => x%5 == 0 ? “Buzz” : “”);!var numbers = inf.Select(x => x.ToString());!!var fizzbuzzer = ! fizzes! .Zip(buzzes, (f, b) => f + b)! .Zip(numbers, (fb, n) => fb == “” ? n : fb);!!fizzbuzzer.Skip(33).First();!// “Fizz”!!fizzbuzzer.Skip(55).First();!// “Buzz”!!fizzbuzzer.Skip(150).First();!// “FizzBuzz”!!fizzbuzzer.Skip(2).First();!// “2”

var inf = Enumerable! .Range(0, int.MaxValue);!!

var fizzes = inf.Select(! x => x%3 == 0 ? “Fizz” : “”);!var buzzes = inf.Select(! x => x%5 == 0 ? “Buzz” : “”);!!

var numbers = inf.Select(! x => x.ToString());

var fizzbuzzer = ! fizzes! .Zip(buzzes,(f, b) => f + b)! .Zip(numbers,! (fb, n) => fb == “” ? n : fb);

fizzbuzzer.Skip(33).First();!// “Fizz”!!

fizzbuzzer.Skip(55).First();!// “Buzz”!!

fizzbuzzer.Skip(150).First();!// “FizzBuzz”!!

fizzbuzzer.Skip(2).First();!// “2”

var inf = Enumerable.Range(0, int.MaxValue);!var fizzes = inf.Select(x => x%3 == 0 ? “Fizz” : “”);!var buzzes = inf.Select(x => x%5 == 0 ? “Buzz” : “”);!var numbers = inf.Select(x => x.ToString());!!var fizzbuzzer = ! fizzes! .Zip(buzzes, (f, b) => f + b)! .Zip(numbers, (fb, n) => fb == “” ? n : fb);!!fizzbuzzer.Skip(33).First();!// “Fizz”!!fizzbuzzer.Skip(55).First();!// “Buzz”!!fizzbuzzer.Skip(150).First();!// “FizzBuzz”!!fizzbuzzer.Skip(2).First();!// “2”

Travel Log

• Forest of Higher Order

• Reduce

• Map

• Filter

• City of Mapcat

• City of Zip

• The Emerald City of FP

–- L. Frank Baum, The Marvelous Land of Oz

“To 'know Thyself' is considered quite an accomplishment.”

What!

How

Execute

Transduce

;; transducer signature!(whatever, input -> whatever) -> (whatever, input -> whatever)

*from: http://clojure.org/transducers

reduce

map

add to

collectionfunction

new[] {1, 2, 3, 4}!.Select(x => x+1); !!

// { 2, 3, 4, 5 }

new[] {1, 2, 3, 4}!.Aggregate(! new List<int>(),! (m, x) => {! m.Add(x+1);! return m;! }).ToArray();!!

// { 2, 3, 4, 5 }

new[] {1, 2, 3, 4}!.Aggregate(! new List<int>(),! (m, x) => {! m.Add(x+1);! return m;! }).ToArray();!!

// { 2, 3, 4, 5 }

new[] {1, 2, 3, 4}!.Aggregate(coll! new typeof(coll),! (m, x) => {! m.Step(x+1);! return m;! });!// { 2, 3, 4, 5 }

FAKE C# CODE!!!

FAKE C# CODE!!!

What!

How

Execute

Transduce

;; map (defn map [f coll] (reduce ! (fn [m x]! (conj m (f x)))! [] coll))

*from: http://youtu.be/6mTbuzafcII

;; map (defn map [f coll] (reduce ! (fn [m x]! (conj m (f x)))! [] coll))

*from: http://youtu.be/6mTbuzafcII

;; map (defn mapping [f]! (fn [step]! (fn [m x]! (step m (f x)))))!!

(defn map [f coll]! (reduce ! ((mapping f) conj) ! [] coll))

*from: http://youtu.be/6mTbuzafcII

(defn mapping [f]! (fn [step]! (fn [m x]! (step m (f x)))))

*from: http://youtu.be/6mTbuzafcII

(defn map [f coll]! (reduce ! ((mapping f) conj) ! [] coll))

*from: http://youtu.be/6mTbuzafcII

;; map (defn map [f coll] (reduce ! (fn [m x]! (conj m (f x)))! [] coll))

*from: http://youtu.be/6mTbuzafcII

;; map (defn mapping [f]! (fn [step]! (fn [m x]! (step m (f x)))))!!

(defn map [f coll]! (reduce ! ((mapping f) conj) ! [] coll))

*from: http://youtu.be/6mTbuzafcII

–- L. Frank Baum, The Marvelous Land of Oz

“[A]lthough I feel that I know a tremendous lot, I am not yet aware how much there is in the

world to find out about. It will take me a little time to discover whether I am very wise or very

foolish.”

Thank you!

Mike Harris@MikeMKHhttp://comp-phil.blogspot.com/

–- L. Frank Baum, The Marvelous Land of Oz

“Everything has to come to an end, sometime.”

Bibliography (conference sessions)

• Rich Hickey - TransducersStrange Loop 2014 https://www.youtube.com/watch?v=6mTbuzafcII

• Rich Hickey - Inside Transducers + more.async Clojure Conj 2014 https://www.youtube.com/watch?v=4KqUvG8HPYo

Bibliography (blog posts)

• Martin Fowler - Collection Pipelines http://martinfowler.com/articles/collection-pipeline/

• Justin Etheredge - A Visual Look at the LINQ SelectMany Operatorhttp://www.codethinked.com/a-visual-look-at-the-linq-selectmany-operator

Bibliography (white papers)

• Graham Hutton - A Tutorial on the Universality and Expressiveness of foldhttp://www.cs.nott.ac.uk/~gmh/fold.pdf

Bibliography (websites)

• Sam Allen - Dot Net Perls http://www.dotnetperls.com/

• lots of smart people - ClojureDocs https://clojuredocs.org/

• Rich Hickey - Transducershttp://clojure.org/transducers

Bibliography (Pluralsight classes)

• Scott Allen - LINQ Architecturehttp://www.pluralsight.com/courses/linq-architecture

• Deborah Kurata - Practical LINQ http://www.pluralsight.com/courses/practical-linq

Bibliography (books)

• Michael Fogus and Chris Houser - The Joy of Clojure http://www.manning.com/fogus2/

Images

• [1] The International Wizard of Oz Club, http://ozclub.org/

• [3-5, 7] Wikipedia, public domain

• [9] W.W. Denslow - The Wonderful Wizard of Oz

• [47] Flicker - Jeremy Schultz, https://www.flickr.com/photos/tao_zhyn/442965594/

• [51] W.W. Denslow - The Marvelous Land of Oz

• [65, 85] W.W. Denslow - The Wonderful Wizard of Oz

• [103] Me taken at dinner by my wife while at Strange Loop 2014