functional programming with ruby - can make you look smart

55
Functional Programming Makes you look smart

Upload: chen-fisher

Post on 26-May-2015

315 views

Category:

Technology


0 download

DESCRIPTION

Functional programming can make you look smart and others feel stupid. Learn how with Ruby code can be found here: https://github.com/chenfisher/functional-programming-with-ruby Youtube: https://www.youtube.com/watch?v=Qzoh8w4OPtU

TRANSCRIPT

Page 1: Functional programming with Ruby - can make you look smart

Functional ProgrammingMakes you look smart

Page 2: Functional programming with Ruby - can make you look smart

“If you ask 100 programmers for their definition, you’ll likely receive 100 different answers”

- “The Joy of Clojure: Thinking the Clojure Way.”

Functional programming?

Page 3: Functional programming with Ruby - can make you look smart

FP - proposed definition

Functional programming makes you look smart and others feel stupid

Page 4: Functional programming with Ruby - can make you look smart
Page 5: Functional programming with Ruby - can make you look smart
Page 6: Functional programming with Ruby - can make you look smart
Page 7: Functional programming with Ruby - can make you look smart

-- Matz

“Some may say Ruby is a bad rip-off of Lisp or Smalltalk, and I admit that”

Page 8: Functional programming with Ruby - can make you look smart

Higher order functions

Page 9: Functional programming with Ruby - can make you look smart

Higher order functions

Do one or more of the following:● Accept a function as an argument● Return a function as the return value

Page 10: Functional programming with Ruby - can make you look smart

Higher order functions

Ruby introduces blocks, procs and lambdas as an instrument for higher order functions

[2, 3, 1].sort { |x,y| y <=> x }

Page 11: Functional programming with Ruby - can make you look smart

higher_order_functions.rb

Time to code

Page 12: Functional programming with Ruby - can make you look smart

Higher order functions

● map, select, inject, reduce, etc.

Page 13: Functional programming with Ruby - can make you look smart

Higher order functions

Prefer this:

result = ["abraham", "isaac", "jacob"].map do |name|

name.capitalizeend

Page 14: Functional programming with Ruby - can make you look smart

Higher order functions

Over this:

result = []

["abraham", "isaac", "jacob"].each do |name|

result << name.capitalizeend

Page 15: Functional programming with Ruby - can make you look smart

Schonfinkeling

Page 16: Functional programming with Ruby - can make you look smart

Schonfinkeling

Is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument -- Wikipedia

f(x, y, z) = f’(x)(y)(z)

Page 17: Functional programming with Ruby - can make you look smart

Moses Schonfinkel

Page 18: Functional programming with Ruby - can make you look smart

Proc#schonfinkel (ruby 1.9)

calc = proc { |op, a, b| a.send(op,

b) }

Schonfinkeling

Page 19: Functional programming with Ruby - can make you look smart

Proc#schonfinkel (ruby 1.9)

calc = proc { |op, a, b| a.send(op,

b) }

add = calc.schonfinkel.(:+)

sub = calc.schonfinkel.(:-)

mult = calc.schonfinkel.(:*)

Schonfinkeling

Page 20: Functional programming with Ruby - can make you look smart

Haskell Brooks Curry

Page 21: Functional programming with Ruby - can make you look smart

Currying

Is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument -- Wikipedia

f(x, y, z) = f’(x)(y)(z)

Page 22: Functional programming with Ruby - can make you look smart

Currying

Proc#curry (ruby 1.9)

calc = proc { |op, a, b| a.send(op,

b) }

add = calc.curry.(:+)

sub = calc.curry.(:-)

mult = calc.curry.(:*)

Page 23: Functional programming with Ruby - can make you look smart

curry.rb

Time to code

Page 24: Functional programming with Ruby - can make you look smart

and side effect free function

Immutability

Page 25: Functional programming with Ruby - can make you look smart

Immutability

Imperative programming:A programming paradigm that describes computation in terms of statements that change a program state

Page 26: Functional programming with Ruby - can make you look smart

Immutability

● Data is immutable (cannot be changed)● Everything is stateless

Page 27: Functional programming with Ruby - can make you look smart

● Output depends only on input (no state)● Will always have the same output for the

same input● No side effect● Memoization● Idempotence

Immutability (pure functions)

Page 28: Functional programming with Ruby - can make you look smart

● Parallelize● Concurrency● result = f(a) + f(b) # can be parallelized● Testing is easier

Immutability (pure functions)

Page 29: Functional programming with Ruby - can make you look smart

immutability.rb

Time to code

Page 30: Functional programming with Ruby - can make you look smart

Immutability

Prefer this:new_options = options.merge({key: value})

Over this:options.merge!({key: value})

Always prefer not to use the bang (!) version of a function

Page 31: Functional programming with Ruby - can make you look smart

Memoization

Page 32: Functional programming with Ruby - can make you look smart

Memoization

Pure functions always return the same output for the same input

No need to re-compute on every call

Page 33: Functional programming with Ruby - can make you look smart

Memoization

# simple memo we use all the time (||=)

def fact(fact_id)

@fact[fact_id] ||= fetch_fact_from_db(fact_id)end

Page 34: Functional programming with Ruby - can make you look smart

memoization.rb

Time to code

Page 35: Functional programming with Ruby - can make you look smart

Tail call optimization

Recursion

Page 36: Functional programming with Ruby - can make you look smart

Immutable data! how do we loop ?!We cannot do this:

i = 0 while i < 10

i = i + 1end(and we shouldn’t - this is ugly)

Recursion

Page 37: Functional programming with Ruby - can make you look smart

Recursion

def factorial(n)

n < 2 ? 1 : n * factorial(n-1)end

factorial 10000 # stack level too deep

Page 38: Functional programming with Ruby - can make you look smart

Recursion

def tail_factorial(n, r)

n < 2 ? r : tail_factorial(n-1, n*r)end

tail_factorial 10000 # OK (if tco enabled in ruby)

Page 39: Functional programming with Ruby - can make you look smart

Recursion

# enable tail call

optimizationRubyVM::InstructionSequence.compile_option = {

:tailcall_optimization => true,

:trace_instruction => false

}

Page 40: Functional programming with Ruby - can make you look smart

recursion.rb

Time to code

Page 41: Functional programming with Ruby - can make you look smart

Enumerators

Page 42: Functional programming with Ruby - can make you look smart

Enumerators

What is the sum of the first 10 numbers divided by 3?

Page 43: Functional programming with Ruby - can make you look smart

Enumerators

# imperative - focuses on 'how'

count = 0; sum = 0; i = 0while count < 10

if i % 3 == 0

sum += i

count += 1

end

i += 1end

puts sum# functional (using enumerators) - focuses on 'what'

(0..10000).select { |x| x%3 == 0 }.take(10).reduce(:+)

Page 44: Functional programming with Ruby - can make you look smart

Enumerators

select, each, inject, etc.. All use enumerators:[1, 2, 3].select.class => # enum

Page 45: Functional programming with Ruby - can make you look smart

Enumerators

If you implement Enumerable in your class, you will have the following methods out of the box:● select● inject● take● etc.

Page 46: Functional programming with Ruby - can make you look smart

enumerators.rb

Time to code

Page 47: Functional programming with Ruby - can make you look smart

Laziness

Page 48: Functional programming with Ruby - can make you look smart

Laziness

What is the sum of the first N numbers divided by 3?(0..Float::INFINITY).select { |x| x%3 == 0 }.take(N).reduce(:+)

Note: Only Chuck Norris can run this

Page 49: Functional programming with Ruby - can make you look smart

Laziness

What is the sum of the first N numbers divided by 3?(0..Float::INFINITY).lazy.select { |x| x%3 == 0 }.take(N).reduce(:+)

Enumerator#Lazy introduced in Ruby 2.0

Page 50: Functional programming with Ruby - can make you look smart

lazy.rb

Time to code

Page 51: Functional programming with Ruby - can make you look smart

log_parser.rb

Log parser

Page 52: Functional programming with Ruby - can make you look smart

Homoiconicity

Page 53: Functional programming with Ruby - can make you look smart
Page 54: Functional programming with Ruby - can make you look smart

Code is data, data is code

Homoiconicity

Page 55: Functional programming with Ruby - can make you look smart

@chenfisher

Thanks!

code can be found here: https://github.com/chenfisher/functional-programming-with-ruby