dr iterate

Post on 08-Apr-2017

50 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Tim Roberts

@cirscagithub.com/beardedtim

Okay MentorBetter Older Brother

JavaScript EvangelistFunctional-ish Developer

Programming is Hard

The Fun Part

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.

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

this.name = name

this.gpa = gpa

this.level = level

}

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

return this.name

}

Student.prototype.getGpa = function(){

return this.gpa

}

Student.prototype.raiseLevel = function(){

this.level = this.level + 1

}

Gary Entsminger- The Tao of Objects

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

safer and more convenient

OOP-ishvar StudentList = function(students){

this.students = students

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

}

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

}

}

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, …

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()

}}

Simon Peyton Jones – Coders at Work

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

of functional programming will be

observed

OOP-ishthis.forEachStudent = function(fn){

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

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

}

}

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

}

OOP-ish

this.raiseLevels = function(){var raiseStudentLevel =

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

}this.forEachStudent(raiseStudentLevel)

}

OOP-ish

var TeacherList = function(teachers){

this.teachers = teachers

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

Functional-ish

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

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

}

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

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

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

What Is Our Worker Doing?

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

}

Functional-ish

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

student.getName())var teachersNames=

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

Regular Objects

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

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

Regular Objects

var getName = obj => obj.name

var studentNames= map(students, getName)

var teachersNames= map(teachers, getName)

Better But Repetitive

var getName = obj => obj.name

var getAge = obj => obj.age

var getLocation = obj => obj.location

What Are We Actually Doing?

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

var getName = pluck(‘name’)

var getAge = pluck(‘age’)

So What About Higher-Order Functions?

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

}

A Higher-Order Function is

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

Let’s Solve Something

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

Let’s Solve Something

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

board.txt

northdelta south

west gamma

moves.txt

What Data Structure?

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

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

}}

What Data Structure?

var board = …

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

}

Why Does It Matter?

Is The Board Always Correct?

Am I Touching The Board?

What’s The Contract?

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

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

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

board.txt

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

const board

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

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

Get Only If…

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

const emptyIndexes = /* ….? */

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

}

Half Way There

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

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

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: ‘.’},…]

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]

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

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

const board

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

const mines

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’))

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

}

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])

Actually Smart People

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

Actually Smart People

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

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

and-love-higherorder-functions

@cirscagithub.com/beardedtim

top related