This presentation gives brief introduction to Functional Programming and how we can apply functional style of programming in Ruby language. The mentioned references are of great help to prepare this presentation. Especially video talks of Dr. Venkat Subramaniam. Some slides are from his presentation.
Functional programming (FP) is becoming popular day by day ! The initial learning curve for some of the functional languages like Lisp, Haskell, OCaml, Scala, Scheme, Clojure, etc. .... (there are many) might be high, but once you know the problem context and power of functions, you will work like a boss ! You will be more declarative than imperative !
Ruby is an Object Oriented (OO) language and we love Ruby, isn't it ? But once you understand the importance of FP, you would certainly want to apply FP concepts while writing Ruby code. In fact, you might have used some of those concepts unknowingly. Yes, we are talking about lambda, proc .. but, that's not all. Learn to unleash the power of Ruby in the hands of a functional programmer! You can write wonderful (and working) ruby code with functional style. In this presentation, I will briefly go through FP basics and then jump over to code examples.
Finally, it's all about changing your mindset! No one has stopped you to become a Boss !
2. Agenda
• WWW of FP
• Spectrum of languages
• OOP and FP
• Imperative vs. Functional
• Examples
• Ruby in a functional style
• References
2
3. Why FP ?
• Programming has become complex
• Multiprocessors are common place
• Multithreading
• But why?
– Domain is only part of the reason
– We have gone too far with OO programming and
mutable state
3
4. Perils of Mutable state
• Mutable state
– Leads to more bugs
– Makes concurrency quite difficult
– Shared mutability
4
7. FP @wikipedia
“In computer science, functional programming is
a programming paradigm that treats
computation as the evaluation of mathematical
functions and avoids state and mutable data. It
emphasizes the application of functions, in
contrast to the imperative programming
style, which emphasizes changes in state.”
7
9. Real world applications of FP
• Erlang: used to implement fault-tolerant
telecommunication system.
• Lisp: used as basis for several applications on
early Apple Macintosh computers.
• Ocaml: use in areas such as financial
analysis, driver verification, industrial robot
programming and static analysis of embedded
software.
9
10. Continued
• Haskell: aerospace systems, hardware design
and web programming.
• Using the functional ideas, Google has
developed framework called MapReduce for
processing massive amounts of data in
parallel.
• Embedded Lisp interpreters add
programmability to some systems, such as
Emacs.
10
11. Continued
• Lisp is used for artificial intelligence
applications.
- Knowledge representation
- machine learning
- Natural language processing
- Modeling of speech and vision
11
12. Principles of FP
• Assignment-less programming
• Immutable state
• Functions as first class citizens
• Higher order functions
• Functions with no side effects
• Referential Transparency
• Lazy evaluation
• Memoization
• Recursion
12
13. Closure
It is closure because it encloses an environment
that is in place when that code block is instantiated.
def get_adder(value)
proc { |x| x + value }
end
adder5 = get_adder(5) adder10 = get_adder(10)
adder5.call(2) # 7 adder10.call(5) #15
adder5.call(4) # 9 adder10.call(8) #18
13
14. Immutability /
No side effect
Higher
order Functions
Functional
Style
Ruby
Groovy
Python
Smalltalk
Clojure
Scala
Purely Functional
Haskell
Erlang
Lisp
14
15. OOP and FP
“OO makes code understandable by
encapsulating moving parts…
FP makes code understandable by minimizing
moving parts.”
- Michael Feathers, author of 'Working with Legacy Code'
15
16. Imperative vs. Functional
Imperative
Specify each step
How to do stuff
Data mutated
Often has side effect
Accepts data/objects
Hard to compose
Functional
More directive in style
What you want to get
Data transformed
Has no side effect
Accepts functions also
Functional composition
16
19. With memoize
require 'memoize'
# https://github.com/djberg96/memoize
include Memoize
def fib(n)
return n if n < 2
fib(n-1) + fib(n-2)
end
memoize(:fib)
fib(35) # fast
# 0.07s
19
23. Haskell :-
[ x+1 | x <- [ x*x | x <- [1..10]]]
Ruby :-
(1..10).collect {|x| x*x }.collect {|x| x+1 }
=> [2,5,10,17,26,37,50,65,82,101]
Lazy evaluation:-
take 10 [ x+1 | x <- [ x*x | x <- [1..]]]
23
24. Lazy evaluation in Ruby 2.0
(0..Float::INFINITY).lazy.map { |x| 2*x }.take(5).to_a
#=> [0, 2, 4, 6, 8]
24
Making an enumerable lazy makes it possible to enumerate infinite
collections.
A lazy enumerable will evaluate the entire chain for each element at a
time, rather than all elements at each stage of the chain.
25. Example 2
What's the sum of the first 10 natural number
whose square value is divisible by 5?
25
26. Imperative
Ruby :
n, num_elements, sum = 1, 0, 0
while num_elements < 10
if n**2 % 5 == 0
sum += n
num_elements += 1
end
n += 1
end
sum #=> 275
26
29. Everything is an expression
message = “”
if found_dog == our_dog
name = found_dog.name
message = "We found our dog #{name}!"
else
message = "No luck"
end
29
30. Continued
message = if found_dog == our_dog
"We found our dog #{found_dog.name}!"
else
"No luck"
end
30
31. Higher-order functions: map
output = []
[1, 2, 3, 4].each do |x|
output << x * 2
end
output # [2, 4, 6, 8]
output = [1, 2, 3, 4].map do |x|
x * 2
end
# [2, 4, 6, 8]
31
32. Higher-order functions: select
output = []
[1, 2, 3, 4].each do |x|
output << x if x > 2
end
output # [3, 4]
output = [1, 2, 3, 4].select do |x|
x > 2
end
# [3, 4]
32
33. Higher-order functions: detect
output = nil
[1, 2, 3, 4].each do |x|
if x > 2
output = x
break
end
end
output # 3
output = [1, 2, 3, 4].detect do |x|
x > 2
end # 3
33
34. Higher-order functions: inject/reduce
total = 0
[1, 2, 3, 4].each do |x|
total += x
end
total # 10
total = [1, 2, 3, 4].inject(0) do |acc, x|
acc + x
end # 10
For simple cases like this:
total = [1, 2, 3, 4].inject(0, :+)
34
35. Higher-order functions: zip
x = [1, 2, 3]
y = [:a, :b, :c]
output = []
0.upto(x.length - 1).each do |idx|
output << [x[idx], y[idx]]
end
output #=> [[1, :a], [2, :b], [3, :c]]
x = [1, 2, 3]
y = [:a, :b, :c]
output = x.zip(y)
#=> [[1, :a], [2, :b], [3, :c]]
35
36. Take away
Let’s try to learn at least
One “Functional” Language
and
experience the power of functions !
36
39. Thank you all for being patient
and hearing me out.
Hope this helps you!
39
Notes de l'éditeur
FP was introduced a long time ago! It was way ahead of its time. Tell Brief history. Electric car = 1900 yearFunctional programming has its roots in lambda calculus, a formal system developed in the 1930s to investigate computability, the Entscheidungsproblem, function definition, function application, and recursion. Many functional programming languages can be viewed as elaborations on the lambda calculus.[1]
Having seen the core principles and spectrum of languages, let’s see where do they fit in a couple of functional principles
Having seen the principles/concepts,So what is the difference between OO and FP ?