SlideShare a Scribd company logo
Functional Programming in Ruby
Koen Handekyn
CEO
Learning FP

it’s (sometimes) (a bit) difficult (in the beginning)
        - you need to retrain your brain -
                  but rewarding


               it’s fun & productive
History
‣ Lambda calculus: 1930’s (Alonzo Church)
‣ Lisp: 1950’s, multi-paradigm language strongly inspired by lambda-calculus
  (symbolic manipulation, rewriting)
‣ ML-family: 1970’s, general purpose functional programming language with
  type inference
‣ Haskell: 1987, 1998, 2010, open standard for functional programming
  research


‣ Other: Clean, F#, Scheme, Scala, Clojure, XSLT, Erlang, SQL, ...
Isn’t all programming functional?
‣ FP proceeds from a startling premise—that we construct programs using
 only pure functions, or functions that avoid side effects like changing
 variables(state), writing to a database or reading from a file.
‣ In a pure functional programming language, everything is a function. we can
 pass them around and “calculate” with them (combine, evaluate or
 partially evaluate, etc).
‣ A function defines a mapping from a “Domain” into the
 “Codomain” (image, range)
Advantages
‣ No mutable data and hence:

‣ No side effects, no implicit hidden state, less bugs.
‣ No variables ! (only values) => optimizations
‣ Can (more easily) be parallelized over cpu’s (multicore), etc. => no
 locks, no race conditions, no deadlocks


‣ Enables Provability (both for humans and computers)
FP vs OO
‣ Whereas an object-oriented mindset will foster the approach of
  defining an application domain as a set of nouns (classes) [ person, ticket,
  etc ]


‣ The functional mind will see the solution as the composition or verbs
  (functions) [ register, sell ]


‣ Though both programmers may in all likelihood generate equivalent results, the
  functional solution will be more succinct, understandable, and reusable. Grand
  claims indeed!
Immutable Objects
‣ An OO pattern that actually originates in FP world
‣ ISO changing a data structure, don’t modify in place but create a new
  object.
‣ In Ruby this is typically the default. Methods that don’t follow this principle
  are assumed ‘dangerous’ and are typically marked with a ‘!’
 • name.reverse => returns a new string that contains the reversed name
 • name.reverse! => replaces the name with the reversed value
Ruby and FP
‣ Ruby is an imperative and OO language with closure support
‣ But we can apply (some) FP principles
‣ It allows to mix and match OO with FP programming style

                                                    A bit of pattern matching
‣ You can’t assume immutability ... it’s a choice   • x, *xs = [1,2,3,4]
‣ No (real) pattern matching (yet)                     x => 1
                                                       xs => [2,3,4]
‣ No lazy evaluation (yet)                          • a,b,tail = [1,2,3,4]
                                                       a => 1
                                                       b => 2
                                                       tail => [3,4]
Recursion
# fibonacci functional through recursion

def fib(count, a = 1, b = 1 , r = [])             r is the
                                                  accumulator
  count == 0 ? r : fib(count-1, b, a+b, r << a)
end

fib(10) # => [1,1,2,3,5,...                   needs a bit of
                                              practice but
                                              once you get
                                              it ...
or also - As opposed to ?
‣ Another look at it is to compare imperative programming languages with
 declarative programming languages
‣ Imperative = emphasize on how something is computed
‣ Declarative = emphasize on what is to be computed and not on
 how
‣ Imperative is counterintuitive when you’re used to imperative
 programming
Taking a look at <<Enumerable >>
First introduce Closure
‣ Closure = an anonymous function block together with a referencing
  environment
‣ Where? javascript, python, ruby, PHP, C# 2.0, java 8! :)
Enumerable#select
(1..10).select { |x| x.odd? }
 => [1, 3, 5, 7, 9]

# imperative style
odds = []
(1..10).each do |n|
  odds << n if n.odd?
end
Enumerable#partition
(1..10).partition { |x| x.odd? }
 => [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

# imperative style
p = [[],[]]
(1..10).each do |n|
  p[0] << n if n.odd?
  p[1] << n unless n.odd?
end
Enumerable#map
(1..10).map { |x| x * 2 }
 => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

# imperative style
doubles = []
(1..10).each do |n|
  doubles << n*2
end
inject & reduce & foldl & foldr
foldl & foldr
Enumerable#reduce
(1..10).reduce { |x,y| x + y } # repeat sum
=> 55

# imperative style
sum = 0
(1..10).each do |n|
  sum += n
end
sum # => 55
Enumerable#reduce
# repeat sum, start with 0
(1..10).reduce(0) { |x,y| x + y }
=> 55

# repeat multiply, start with 1
(1..10).reduce(1) { |x,y| x * y }
=> 3628800

# or ‘for real’ :)
(1..10).inject(:+) => 55
(1..10).inject(:*) => 3628800
Enumerator#group_by
(1..6).group_by { |i| i%3 }
=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

# imperative style
p = {}
(1..6).each do |n|
  k = n%3
  p[k] ||= []
  p[k] << n
end
Enumerable#sort
%w(rhea kea flea).sort
#=> ["flea", "kea", "rhea"]

(1..10).sort {|a,b| b <=> a}
#=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

# imperative style
# ... have fun ...
(: take a breath :)
Currying
‣ In mathematics and computer science, currying is the technique of
 transforming a function that takes multiple arguments (or a tuple of
 arguments) in such a way that it can be called as a chain of functions, each
 with a single argument (partial application). It was originated by Moses
 Schönfinkel and later re-discovered by Haskell Curry.
‣ curry(int, int => bool) = int => (int => bool)
Functions as Values in Ruby
inc = lambda { |x| x + 1 }
inc = ->(x) { x + 1 }
inc.(4) => 5

add = lambda { |x,y| x + y }
add = ->(x,y) { x + y }
add.(2,3) => 5
Constants are Functions
constant = ->(c,x) { c }.curry

hello = constant.(“hello”)
hello.(1) => “hello”
hello.(“eugen”) => “hello”
Composition
identity = ->(x) { x } # a closure
power = ->(base, x) { base**x }.curry

sum_of = ->(f, xs, i=0) { xs.inject(i) { |a,i| a+=f.(i) } }.curry

sum_of_numbers = sum_of.(identity)
                                          a Higher Order
sum_of_power2s = sum_of.(power.(2))       function takes a
sum_of_squares = sum_of.(square)          function as
                                          parameter
# usage
sum_of_numbers.(0..10) # => 55
sum_of_squares.(0..10) # => 2047
sum_of.( power.(3) ).(0..10) # => 88573
Constants are Functions
constant = ->(c,x) { c }.curry
sum_of = ->(f, r, i=0) { r.inject(i) { |a,i| a+=f.(i) } }.curry

word_count = sum_of.( constant.(1) )

word_count.( %w(welcome to the world of fp) ) => 6
Currying and Partial Evaluation
power = ->(base, x) { base**x }.curry
power.(10,2) # => 100
power.(10).(2) # => 100

power2 = power.(2) # partial evaluation
power2.(3) # => 8

add = ->(x,y) { x + y }.curry
add.(2,3) => 5

inc = add.(1) # partial evaluation
inc.(3) => 4
Currying and Partial Evaluation
# meta functional programming ;)
send = ->(m, o) { o.send(m) }.curry
length_of = send.(:length)

length_of.(“koen”) # => 4
length_of.([12,4,25,32,[2,2]]) # => 5
More Composition
# from previous
length_of = ->(o) { o.length }
sum_of = ->(f, r, i=0) { r.inject(i) { |a,i| a+=f.(i) } }.curry

# compose
total_length_off = sum_of.(length_of)

# use
total_length_off.( ['koen','ciprian','eugen'] ) # => 16
total_length_off.( [ [2,3,4], "koen", [3,4,5] ] ) # => 10
Playing with boxes
box1 = { width: 230, heigth: 304 }
box2 = { width: 340, heigth: 243 }

by_key = ->(k, o) { o[k] }.curry
by_width = by_key.(:width)

taller = ->(f, a, b) { f.(a) > f.(b) }.curry

taller.(by_width, box1, box2) # => false
taller.(by_key.(:heigth)).(box1,box2) # => true
More boxes
compose = ->(f,g,x) { g.(f.(x)) }.curry
square = ->(x) { x*x }

square_width = compose.(by_width).(square)
square_width.(box1) # => 52900

square_height = compose.(by_key.(:heigth)).(square)
square_height.(box1) # => 92416
More composition
map = ->(f, a) { a.map { |x| f.(x) }}.curry # turn method into lambda

squares = ->(a) { map.(square).(a) }
squares = map.(square) # nicer through composition, not ? :)

sum = ->(a) { a.inject(0,:+) }
square_of_sum = compose.(sum).(square)

after = compose
sum_of_squares = after.(squares).(sum)

square_of_sum.([2,3]) # => 25
sum_of_squares.([2,3]) # => 13
square_of_sum.([2,3,4]) # => 81
sum_of_squares.([2,3,4]) # => 29
More composition
book = [ %w(this is a long sentence), %w(this is a short), %w(yes) ]

foldl = ->(f, arr) { arr.inject { |r, x| f.(r, x) } }.curry

add = ->(a,b) { a+b }
div = ->(a,b) { a*1.0/b }
length = ->(x) { x.length }

sum = foldl.(add)
divide = foldl.(div)

pair = parallel = ->(f,g,x) { [f.(x), g.(x) ] }.curry

average = ->(a) { sum.(a) / length.(a) }
average = after.( pair.(sum).(length) ).(divide)

average_wordcount = after.( map.(length) ).(average) # => 3.33
More Composition
book = [
 %w(this is a long sentence),
 %w(this is a short),
 %w(yes) ]

flatten = ->(arr) { arr.flatten } # convert to lambda

wordlengths = after.( flatten ).( map.(length) )
average_wordlength = after.(wordlengths).(average)

average_wordlength.(book) # => 3.4
Liquer Stores
liquer_stores   = []
liquer_stores   << {   name:   "total", d: 2.0, price: 32.0 }
liquer_stores   << {   name:   "shell", d: 2.6, price: 28.5 }
liquer_stores   << {   name:   "esso", d: 3.2, price: 41.0 }
liquer_stores   << {   name:   "q8", d: 3.5, price: 22.0 }
liquer_stores   << {   name:   "shell", d: 4.5, price: 19.0 }
liquer_stores   << {   name:   "q8", d: 5.5, price: 18.0 }
Imperative Liquer
def cheap_boose_nearby (liquer_stores)
  min = liquer_stores[0][:price]
  liquer_stores.each do |store|
    if store[:d] < 5.0 then
      price = store[:price]
      price = price * 0.9 if store[:name] == "shell"
      min = price if price < min
    end
  end
  min
end
Declarative Liquer
def expensive_boose_nearby (liquer_stores)

  nearby = ->(d, x) { x[:d] < d }.curry
  near = nearby.(5.0)
  myPrice = ->(x) {
    x[:name] == "shell" ? x[:price]*0.9 : x[:price]
  }

  liquer_stores.
    find_all(&near).                recognize
    collect(&myPrice).              SQL ?
    max
end
Generators / Sequence / Infinite ...
# Functions that return a sequence of values
# Here: fibonacci as infinite yielder

fibonacci = Enumerator.new do |list|
  a = b = 1
  loop { list.yield a; a,b = b,a+b }
end

fibonacci.take(10) # [1, .. , 55]
fibonacci.take(15) # [1, .. , 377, 610]
Enumerable as Class
class Fibs
  include Enumerable
  def each
    a = b = 1;
    loop { yield a; a,b = b,a+b };
  end
end

Fibs.new.take(10)
Merci

More Related Content

What's hot

Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operations
Megha V
 
Python : Regular expressions
Python : Regular expressionsPython : Regular expressions
Python : Regular expressions
Emertxe Information Technologies Pvt Ltd
 
Array&amp;string
Array&amp;stringArray&amp;string
Array&amp;string
chanchal ghosh
 
Python programming -Tuple and Set Data type
Python programming -Tuple and Set Data typePython programming -Tuple and Set Data type
Python programming -Tuple and Set Data type
Megha V
 
Python programming : List and tuples
Python programming : List and tuplesPython programming : List and tuples
Python programming : List and tuples
Emertxe Information Technologies Pvt Ltd
 
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCEFUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
Venugopalavarma Raja
 
Python : Dictionaries
Python : DictionariesPython : Dictionaries
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonTendayi Mawushe
 
Parts of python programming language
Parts of python programming languageParts of python programming language
Parts of python programming language
Megha V
 
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCEFUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
Venugopalavarma Raja
 
Python Datatypes by SujithKumar
Python Datatypes by SujithKumarPython Datatypes by SujithKumar
Python Datatypes by SujithKumar
Sujith Kumar
 
Python programming Part -6
Python programming Part -6Python programming Part -6
Python programming Part -6
Megha V
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
Aiman Hud
 
13. Java text processing
13.  Java text processing13.  Java text processing
13. Java text processing
Intro C# Book
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta
 
Python Modules, Packages and Libraries
Python Modules, Packages and LibrariesPython Modules, Packages and Libraries
Python Modules, Packages and Libraries
Venugopalavarma Raja
 

What's hot (17)

Python programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operationsPython programming: Anonymous functions, String operations
Python programming: Anonymous functions, String operations
 
Python : Regular expressions
Python : Regular expressionsPython : Regular expressions
Python : Regular expressions
 
Core C#
Core C#Core C#
Core C#
 
Array&amp;string
Array&amp;stringArray&amp;string
Array&amp;string
 
Python programming -Tuple and Set Data type
Python programming -Tuple and Set Data typePython programming -Tuple and Set Data type
Python programming -Tuple and Set Data type
 
Python programming : List and tuples
Python programming : List and tuplesPython programming : List and tuples
Python programming : List and tuples
 
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCEFUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
FUNCTIONS IN PYTHON. CBSE +2 COMPUTER SCIENCE
 
Python : Dictionaries
Python : DictionariesPython : Dictionaries
Python : Dictionaries
 
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in Python
 
Parts of python programming language
Parts of python programming languageParts of python programming language
Parts of python programming language
 
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCEFUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
 
Python Datatypes by SujithKumar
Python Datatypes by SujithKumarPython Datatypes by SujithKumar
Python Datatypes by SujithKumar
 
Python programming Part -6
Python programming Part -6Python programming Part -6
Python programming Part -6
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
 
13. Java text processing
13.  Java text processing13.  Java text processing
13. Java text processing
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Python Modules, Packages and Libraries
Python Modules, Packages and LibrariesPython Modules, Packages and Libraries
Python Modules, Packages and Libraries
 

Similar to Functional programming in ruby

Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
Scott Leberknight
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
Svet Ivantchev
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
Aleksandar Veselinovic
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
Debasish Ghosh
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
Platonov Sergey
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in Python
Anoop Thomas Mathew
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
UC San Diego
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
niklal
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
carliotwaycave
 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskell
ujihisa
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
Narong Intiruk
 
Very basic functional design patterns
Very basic functional design patternsVery basic functional design patterns
Very basic functional design patterns
Tomasz Kowal
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
Software Guru
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
Luis Atencio
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
Daniel Sebban
 
Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)
Guy Lebanon
 

Similar to Functional programming in ruby (20)

Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in Python
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Python lecture 05
Python lecture 05Python lecture 05
Python lecture 05
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskell
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Very basic functional design patterns
Very basic functional design patternsVery basic functional design patterns
Very basic functional design patterns
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Data Analysis with R (combined slides)
Data Analysis with R (combined slides)Data Analysis with R (combined slides)
Data Analysis with R (combined slides)
 

Recently uploaded

Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 

Recently uploaded (20)

Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 

Functional programming in ruby

  • 1. Functional Programming in Ruby Koen Handekyn CEO
  • 2. Learning FP it’s (sometimes) (a bit) difficult (in the beginning) - you need to retrain your brain - but rewarding it’s fun & productive
  • 3. History ‣ Lambda calculus: 1930’s (Alonzo Church) ‣ Lisp: 1950’s, multi-paradigm language strongly inspired by lambda-calculus (symbolic manipulation, rewriting) ‣ ML-family: 1970’s, general purpose functional programming language with type inference ‣ Haskell: 1987, 1998, 2010, open standard for functional programming research ‣ Other: Clean, F#, Scheme, Scala, Clojure, XSLT, Erlang, SQL, ...
  • 4. Isn’t all programming functional? ‣ FP proceeds from a startling premise—that we construct programs using only pure functions, or functions that avoid side effects like changing variables(state), writing to a database or reading from a file. ‣ In a pure functional programming language, everything is a function. we can pass them around and “calculate” with them (combine, evaluate or partially evaluate, etc). ‣ A function defines a mapping from a “Domain” into the “Codomain” (image, range)
  • 5. Advantages ‣ No mutable data and hence: ‣ No side effects, no implicit hidden state, less bugs. ‣ No variables ! (only values) => optimizations ‣ Can (more easily) be parallelized over cpu’s (multicore), etc. => no locks, no race conditions, no deadlocks ‣ Enables Provability (both for humans and computers)
  • 6. FP vs OO ‣ Whereas an object-oriented mindset will foster the approach of defining an application domain as a set of nouns (classes) [ person, ticket, etc ] ‣ The functional mind will see the solution as the composition or verbs (functions) [ register, sell ] ‣ Though both programmers may in all likelihood generate equivalent results, the functional solution will be more succinct, understandable, and reusable. Grand claims indeed!
  • 7. Immutable Objects ‣ An OO pattern that actually originates in FP world ‣ ISO changing a data structure, don’t modify in place but create a new object. ‣ In Ruby this is typically the default. Methods that don’t follow this principle are assumed ‘dangerous’ and are typically marked with a ‘!’ • name.reverse => returns a new string that contains the reversed name • name.reverse! => replaces the name with the reversed value
  • 8. Ruby and FP ‣ Ruby is an imperative and OO language with closure support ‣ But we can apply (some) FP principles ‣ It allows to mix and match OO with FP programming style A bit of pattern matching ‣ You can’t assume immutability ... it’s a choice • x, *xs = [1,2,3,4] ‣ No (real) pattern matching (yet) x => 1 xs => [2,3,4] ‣ No lazy evaluation (yet) • a,b,tail = [1,2,3,4] a => 1 b => 2 tail => [3,4]
  • 9. Recursion # fibonacci functional through recursion def fib(count, a = 1, b = 1 , r = []) r is the accumulator count == 0 ? r : fib(count-1, b, a+b, r << a) end fib(10) # => [1,1,2,3,5,... needs a bit of practice but once you get it ...
  • 10. or also - As opposed to ? ‣ Another look at it is to compare imperative programming languages with declarative programming languages ‣ Imperative = emphasize on how something is computed ‣ Declarative = emphasize on what is to be computed and not on how ‣ Imperative is counterintuitive when you’re used to imperative programming
  • 11. Taking a look at <<Enumerable >>
  • 12. First introduce Closure ‣ Closure = an anonymous function block together with a referencing environment ‣ Where? javascript, python, ruby, PHP, C# 2.0, java 8! :)
  • 13. Enumerable#select (1..10).select { |x| x.odd? } => [1, 3, 5, 7, 9] # imperative style odds = [] (1..10).each do |n| odds << n if n.odd? end
  • 14. Enumerable#partition (1..10).partition { |x| x.odd? } => [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]] # imperative style p = [[],[]] (1..10).each do |n| p[0] << n if n.odd? p[1] << n unless n.odd? end
  • 15. Enumerable#map (1..10).map { |x| x * 2 } => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] # imperative style doubles = [] (1..10).each do |n| doubles << n*2 end
  • 16. inject & reduce & foldl & foldr
  • 18. Enumerable#reduce (1..10).reduce { |x,y| x + y } # repeat sum => 55 # imperative style sum = 0 (1..10).each do |n| sum += n end sum # => 55
  • 19. Enumerable#reduce # repeat sum, start with 0 (1..10).reduce(0) { |x,y| x + y } => 55 # repeat multiply, start with 1 (1..10).reduce(1) { |x,y| x * y } => 3628800 # or ‘for real’ :) (1..10).inject(:+) => 55 (1..10).inject(:*) => 3628800
  • 20. Enumerator#group_by (1..6).group_by { |i| i%3 } => {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]} # imperative style p = {} (1..6).each do |n| k = n%3 p[k] ||= [] p[k] << n end
  • 21. Enumerable#sort %w(rhea kea flea).sort #=> ["flea", "kea", "rhea"] (1..10).sort {|a,b| b <=> a} #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] # imperative style # ... have fun ...
  • 22. (: take a breath :)
  • 23. Currying ‣ In mathematics and computer science, currying is the technique of transforming a function that takes multiple arguments (or a tuple of arguments) in such a way that it can be called as a chain of functions, each with a single argument (partial application). It was originated by Moses Schönfinkel and later re-discovered by Haskell Curry. ‣ curry(int, int => bool) = int => (int => bool)
  • 24. Functions as Values in Ruby inc = lambda { |x| x + 1 } inc = ->(x) { x + 1 } inc.(4) => 5 add = lambda { |x,y| x + y } add = ->(x,y) { x + y } add.(2,3) => 5
  • 25. Constants are Functions constant = ->(c,x) { c }.curry hello = constant.(“hello”) hello.(1) => “hello” hello.(“eugen”) => “hello”
  • 26. Composition identity = ->(x) { x } # a closure power = ->(base, x) { base**x }.curry sum_of = ->(f, xs, i=0) { xs.inject(i) { |a,i| a+=f.(i) } }.curry sum_of_numbers = sum_of.(identity) a Higher Order sum_of_power2s = sum_of.(power.(2)) function takes a sum_of_squares = sum_of.(square) function as parameter # usage sum_of_numbers.(0..10) # => 55 sum_of_squares.(0..10) # => 2047 sum_of.( power.(3) ).(0..10) # => 88573
  • 27. Constants are Functions constant = ->(c,x) { c }.curry sum_of = ->(f, r, i=0) { r.inject(i) { |a,i| a+=f.(i) } }.curry word_count = sum_of.( constant.(1) ) word_count.( %w(welcome to the world of fp) ) => 6
  • 28. Currying and Partial Evaluation power = ->(base, x) { base**x }.curry power.(10,2) # => 100 power.(10).(2) # => 100 power2 = power.(2) # partial evaluation power2.(3) # => 8 add = ->(x,y) { x + y }.curry add.(2,3) => 5 inc = add.(1) # partial evaluation inc.(3) => 4
  • 29. Currying and Partial Evaluation # meta functional programming ;) send = ->(m, o) { o.send(m) }.curry length_of = send.(:length) length_of.(“koen”) # => 4 length_of.([12,4,25,32,[2,2]]) # => 5
  • 30. More Composition # from previous length_of = ->(o) { o.length } sum_of = ->(f, r, i=0) { r.inject(i) { |a,i| a+=f.(i) } }.curry # compose total_length_off = sum_of.(length_of) # use total_length_off.( ['koen','ciprian','eugen'] ) # => 16 total_length_off.( [ [2,3,4], "koen", [3,4,5] ] ) # => 10
  • 31. Playing with boxes box1 = { width: 230, heigth: 304 } box2 = { width: 340, heigth: 243 } by_key = ->(k, o) { o[k] }.curry by_width = by_key.(:width) taller = ->(f, a, b) { f.(a) > f.(b) }.curry taller.(by_width, box1, box2) # => false taller.(by_key.(:heigth)).(box1,box2) # => true
  • 32. More boxes compose = ->(f,g,x) { g.(f.(x)) }.curry square = ->(x) { x*x } square_width = compose.(by_width).(square) square_width.(box1) # => 52900 square_height = compose.(by_key.(:heigth)).(square) square_height.(box1) # => 92416
  • 33. More composition map = ->(f, a) { a.map { |x| f.(x) }}.curry # turn method into lambda squares = ->(a) { map.(square).(a) } squares = map.(square) # nicer through composition, not ? :) sum = ->(a) { a.inject(0,:+) } square_of_sum = compose.(sum).(square) after = compose sum_of_squares = after.(squares).(sum) square_of_sum.([2,3]) # => 25 sum_of_squares.([2,3]) # => 13 square_of_sum.([2,3,4]) # => 81 sum_of_squares.([2,3,4]) # => 29
  • 34. More composition book = [ %w(this is a long sentence), %w(this is a short), %w(yes) ] foldl = ->(f, arr) { arr.inject { |r, x| f.(r, x) } }.curry add = ->(a,b) { a+b } div = ->(a,b) { a*1.0/b } length = ->(x) { x.length } sum = foldl.(add) divide = foldl.(div) pair = parallel = ->(f,g,x) { [f.(x), g.(x) ] }.curry average = ->(a) { sum.(a) / length.(a) } average = after.( pair.(sum).(length) ).(divide) average_wordcount = after.( map.(length) ).(average) # => 3.33
  • 35. More Composition book = [ %w(this is a long sentence), %w(this is a short), %w(yes) ] flatten = ->(arr) { arr.flatten } # convert to lambda wordlengths = after.( flatten ).( map.(length) ) average_wordlength = after.(wordlengths).(average) average_wordlength.(book) # => 3.4
  • 36. Liquer Stores liquer_stores = [] liquer_stores << { name: "total", d: 2.0, price: 32.0 } liquer_stores << { name: "shell", d: 2.6, price: 28.5 } liquer_stores << { name: "esso", d: 3.2, price: 41.0 } liquer_stores << { name: "q8", d: 3.5, price: 22.0 } liquer_stores << { name: "shell", d: 4.5, price: 19.0 } liquer_stores << { name: "q8", d: 5.5, price: 18.0 }
  • 37. Imperative Liquer def cheap_boose_nearby (liquer_stores) min = liquer_stores[0][:price] liquer_stores.each do |store| if store[:d] < 5.0 then price = store[:price] price = price * 0.9 if store[:name] == "shell" min = price if price < min end end min end
  • 38. Declarative Liquer def expensive_boose_nearby (liquer_stores) nearby = ->(d, x) { x[:d] < d }.curry near = nearby.(5.0) myPrice = ->(x) { x[:name] == "shell" ? x[:price]*0.9 : x[:price] } liquer_stores. find_all(&near). recognize collect(&myPrice). SQL ? max end
  • 39. Generators / Sequence / Infinite ... # Functions that return a sequence of values # Here: fibonacci as infinite yielder fibonacci = Enumerator.new do |list| a = b = 1 loop { list.yield a; a,b = b,a+b } end fibonacci.take(10) # [1, .. , 55] fibonacci.take(15) # [1, .. , 377, 610]
  • 40. Enumerable as Class class Fibs include Enumerable def each a = b = 1; loop { yield a; a,b = b,a+b }; end end Fibs.new.take(10)
  • 41. Merci