Dr iterate

49
Doctor Iterate OR HOW I LEARNED TO STOP WORRYING AND LOVE HIGHER-ORDER FUNCTIONS http://www.slideshare.net/TimothyRoberts8/ dr-iterate-or-how-i-learned-to-stop-worrying-and-love-higherorder-functions

Transcript of Dr iterate

Page 1: Dr iterate

Doctor IterateOR HOW I LEARNED TO STOP WORRYING AND LOVE HIGHER-ORDER FUNCTIONS

http://www.slideshare.net/TimothyRoberts8/dr-iterate-or-how-i-learned-to-stop-worrying-and-love-higherorder-functions

Page 2: Dr iterate

Tim Roberts

@cirscagithub.com/beardedtim

Okay MentorBetter Older Brother

JavaScript EvangelistFunctional-ish Developer

Page 3: Dr iterate

Programming is Hard

Page 4: Dr iterate

The Fun Part

Page 5: Dr iterate

Joe Armstrong - Coders At Work

I think the lack of reusability comes in object-oriented languages, not functional

languages. Because the problem with object-oriented languages is

they’ve got all this implicit environment that they carry

around with them.

Page 6: Dr iterate

OOP-ishvar Student = function(name, gpa, level) {

this.name = name

this.gpa = gpa

this.level = level

}

Page 7: Dr iterate

OOP-ishStudent.prototype.getName = function(){

return this.name

}

Student.prototype.getGpa = function(){

return this.gpa

}

Student.prototype.raiseLevel = function(){

this.level = this.level + 1

}

Page 8: Dr iterate

Gary Entsminger- The Tao of Objects

Putting operations and behaviors in one place makes good sense; it’s

safer and more convenient

Page 9: Dr iterate

OOP-ishvar StudentList = function(students){

this.students = students

this.getNames = function(){/* …. */

}

this.raiseStudentsLevel = function(){/* …. */

}

}

Page 10: Dr iterate

Imperative-ishvar students = […]

var names = []

for(var = i; i < students.length; i++){

var name = students[i].getName()

names.push(name)

}

console.log(names) // Katie, Emmie, Timi, …

Page 11: Dr iterate

OOP-ishthis.getNames = function(){

var names = []for(var = i; i < this.students.length; i++){

var name = this.students[i].getName()names.push(name)

}return names

}

this.raiseStudentsLevel = function(){for(var = i; i < this.students.length; i++){

var student= this.students[i]student.raiseLevel()

}}

Page 12: Dr iterate

Simon Peyton Jones – Coders at Work

When the limestone of imperative programming is worn away, the granite

of functional programming will be

observed

Page 13: Dr iterate

OOP-ishthis.forEachStudent = function(fn){

for( var i = 0; i < this.students.length; i++){

var student = this.students[i]fn(student,i,this.students)

}

}

Page 14: Dr iterate

OOP-ish

this.getNames = function(){var names = [],

getName = function(student, i, this.students){var name = studet.getName()names.push(name)

}this.forEachStudent(getName)return names

}

Page 15: Dr iterate

OOP-ish

this.raiseLevels = function(){var raiseStudentLevel =

function(student,i,students){student.raiseLevel()

}this.forEachStudent(raiseStudentLevel)

}

Page 16: Dr iterate

OOP-ish

var TeacherList = function(teachers){

this.teachers = teachers

this.getNames = /* ….? */ }

Page 17: Dr iterate

Functional-ish

function forEach(arr,fn){for(var i = 0; i < arr.length; i++){

fn(arr[i],i,arr)}

}

Page 18: Dr iterate

Functional-ishvar studentNames = []forEach(StudentList.students,(student) => {

studentNames.push(student.getName())})var teachersNames= []forEach(TeacherList.teachers,(teacher) => {

teacherNames.push(teacher.getName())})

Page 19: Dr iterate

What Is Our Worker Doing?

Page 20: Dr iterate

Functional-ish

function map(arr,fn){var result = []for(var i = 0; i < arr.length; i++){

var newVal = fn(arr[i],i,arr)result.push(newVal)

}return result

}

Page 21: Dr iterate

Functional-ish

var studentNames = map(StudentList.students, student =>

student.getName())var teachersNames=

map(TeacherList.teachers, teacher => teacher.getName())

Page 22: Dr iterate

Regular Objects

var studentNames = map(students, student => student.name)

var teachersNames= map(teachers, teacher => teacher.name)

Page 23: Dr iterate

Regular Objects

var getName = obj => obj.name

var studentNames= map(students, getName)

var teachersNames= map(teachers, getName)

Page 24: Dr iterate

Better But Repetitive

var getName = obj => obj.name

var getAge = obj => obj.age

var getLocation = obj => obj.location

Page 25: Dr iterate

What Are We Actually Doing?

var pluck = key => obj =>obj[key]

var getName = pluck(‘name’)

var getAge = pluck(‘age’)

Page 26: Dr iterate

So What About Higher-Order Functions?

Page 27: Dr iterate

A Higher-Order Function is

A function that accepts a function:function map(arr,fn){

var result = []for(var i = 0; i < arr.length; i++){

var newVal = fn(arr[i],i,arr)result.push(newVal)

}return result

}

Page 28: Dr iterate

A Higher-Order Function is

A function that returns a function:var pluck = key => obj => obj[key]

Page 29: Dr iterate

Let’s Solve Something

https://github.com/mlotstein/StarFleet-Mine-Clearing-Exercise/blob/master/README.md

Page 30: Dr iterate

Let’s Solve Something

..A..A…A..A..

board.txt

northdelta south

west gamma

moves.txt

Page 31: Dr iterate

What Data Structure?

var Board = function(){this.board = …

this.drawBoard = function(center){/* .... */

}}

Page 32: Dr iterate

What Data Structure?

var board = …

var makeBoard = (board,center){/* .... */

}

Page 33: Dr iterate

Why Does It Matter?

Is The Board Always Correct?

Am I Touching The Board?

What’s The Contract?

Page 34: Dr iterate

Reusable Solutionsconst board = str => str.split(‘\n’)

.map(row => row.split(‘’))

..A..A…A..A..

board.txt

[[‘.’,’.’,’A’,’.’,’.’],[‘A’,’.’,’.’,’.’,’A’],[‘.’,’.’,’A’,’.’,’.’]]

const board

Page 35: Dr iterate

Reusable Solutionsconst board = str => str.split(‘\n’)

.map(row => row.split(‘’))

Page 36: Dr iterate

Get Only If…

const row = [‘.’,’.’,’A’,’.’,’.’]

const emptyIndexes = /* ….? */

Page 37: Dr iterate

Get Only If…const filter = (arr,pred) => {

const result = []for(let i = 0; i < arr.length; i++){

const item = arr[i] if(pred(item,i,arr){

result.push(item)}

}return result

}

Page 38: Dr iterate

Half Way There

const row = [‘.’,’.’,’A’,’.’,’.’]

const emptyIndexes = filter(row,char => char === ‘.’)

Page 39: Dr iterate

Map To The Rescue!

const row = [‘.’,’.’,’A’,’.’,’.’]

const emptyIndexes = row.map( (char, i) => ({ index: i, char}) )

.filter({char} => char === ‘.’)

console.log(emptyIndexes) // [{index: 0, char: ‘.’},…]

Page 40: Dr iterate

Loop ALL The Times

const row = [‘.’,’.’,’A’,’.’,’.’]

const emptyIndexes = row.map( (char, i) => ({ index: i, char}) )

.filter({char} => char === ‘.’) .map(pluck(‘index’))

console.log(emptyIndexes) // [0,1,3,4]

Page 41: Dr iterate

How Does That Help Us?const mines = board => /* ….? */

[[‘.’,’.’,’A’,’.’,’.’],[‘A’,’.’,’.’,’.’,’A’],[‘.’,’.’,’A’,’.’,’.’]]

const board

[[0,2],[1,0],[1,4],[2,0]]

const mines

Page 42: Dr iterate

How Does That Help Us?const minesFromRows = (row,y) =>

row.map((char, x) => ({location: [x,y],char})

.filter({char} => char !== ‘.’)

const mineCoords = board => board.map(minesFromRows)

.filter(row => row.length) .reduce((list,row) =>

list.concat(row),[]) .map(pluck(‘location’))

Page 43: Dr iterate

Reduce Down For What?const reduce = (arr,fn,start) => {

let result = startfor(let i = 0; i < arr.length; i++){

const curr = arr[i],pre = result

result = fn(pre,curr,i, arr)}return result

}

Page 44: Dr iterate

Reduce, Reuse, Recycle

const biggestDelta = ([x1,y1],[x2,y2] =>

[Math.max(x1,x2),Math.max(y1,y2)]

const furthestPoints =(mines,[centerX,centerY]) =>

mines.reduce(biggestDelta,[0,0])

Page 46: Dr iterate

Actually Smart People

https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q

Page 47: Dr iterate

Actually Smart People

https://github.com/getify/Functional-Light-JS

Page 49: Dr iterate

http://www.slideshare.net/TimothyRoberts/dr-iterate-or-how-i-learned-to-stop-worrying-

and-love-higherorder-functions

@cirscagithub.com/beardedtim