Functional programming with Ruby - can make you look smart

55
Functional Programming Makes you look smart

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 of Functional programming with Ruby - can make you look smart

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