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
Ad

More Related Content

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
Megha V
 
Python : Regular expressions
Python : Regular expressionsPython : Regular expressions
Python : Regular expressions
Emertxe Information Technologies Pvt Ltd
 
Core C#
Core C#Core C#
Core C#
Jussi Pohjolainen
 
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
Python : Dictionaries
Emertxe Information Technologies Pvt Ltd
 
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
Tendayi 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
 
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 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
 
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
 
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
Tendayi 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
 

Similar to Functional programming in ruby (20)

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
 
Python lecture 05
Python lecture 05Python lecture 05
Python lecture 05
Tanwir Zaman
 
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
 
Introduction to Python Prog. - Lecture 2
Introduction to Python Prog. - Lecture 2Introduction to Python Prog. - Lecture 2
Introduction to Python Prog. - Lecture 2
Faculty of Computers and Informatics, Suez Canal University, Ismailia, Egypt
 
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
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
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
 
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
 
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
 
Ad

Recently uploaded (20)

2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Ad

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