39
Functional Programming (FP) & Ruby in Functional style - Niranjan Sarade 1

Functional programming and ruby in functional style

Embed Size (px)

DESCRIPTION

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 !

Citation preview

Page 1: Functional programming and ruby in functional style

1

Functional Programming (FP) &

Ruby in Functional style

- Niranjan Sarade

Page 2: Functional programming and ruby in functional style

2

Agenda

• WWW of FP• Spectrum of languages• OOP and FP• Imperative vs. Functional• Examples• Ruby in a functional style• References

Page 3: Functional programming and ruby in functional style

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

Page 4: Functional programming and ruby in functional style

4

Perils of Mutable state

• Mutable state

– Leads to more bugs

– Makes concurrency quite difficult

– Shared mutability

Page 5: Functional programming and ruby in functional style

5

What’s Old is New again!

Page 6: Functional programming and ruby in functional style

6

y = f(x)

Page 7: Functional programming and ruby in functional style

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.”

Page 8: Functional programming and ruby in functional style

8

Spectrum of Languages Non-functional Hybrid Functional

Java

C++

C#

Ruby

Groovy

Scala

F#

Clojure

Haskell

LISP

Erlang

Stati

cally

ty

ped

Dyn

amic

ally

ty

ped

Page 9: Functional programming and ruby in functional style

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.

Page 10: Functional programming and ruby in functional style

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.

Page 11: Functional programming and ruby in functional style

11

Continued

• Lisp is used for artificial intelligence applications.

- Knowledge representation- machine learning- Natural language processing- Modeling of speech and vision

Page 12: Functional programming and ruby in functional style

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

Page 13: Functional programming and ruby in functional style

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) #15adder5.call(4) # 9 adder10.call(8) #18

Page 14: Functional programming and ruby in functional style

14

Immutability / No side effect

Higher order Functions

Functional Style

Ruby GroovyPython

SmalltalkClojure

Scala

Purely Functional

HaskellErlang

Lisp

Page 15: Functional programming and ruby in functional style

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'

Page 16: Functional programming and ruby in functional style

16

Imperative vs. Functional

ImperativeSpecify each stepHow to do stuffData mutatedOften has side effectAccepts data/objectsHard to compose

FunctionalMore directive in styleWhat you want to getData transformedHas no side effectAccepts functions alsoFunctional composition

Page 17: Functional programming and ruby in functional style

17

Memoization

Page 18: Functional programming and ruby in functional style

18

Without memoize

def fib(n) return n if n < 2 fib(n-1) + fib(n-2)end

fib(35) # slow

#2.879s

Page 19: Functional programming and ruby in functional style

19

With memoizerequire '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

Page 20: Functional programming and ruby in functional style

20

Example 1

Squares of Integers

Page 21: Functional programming and ruby in functional style

21

Java & Clojure

public class Squint { public static void main(String args[]) { for (int i=1; i<=25; i++) System.out.println(i*i); }}

Clojure : (take 25 (squares-of (integers))

(1 2 3 4 5 6 7 8 ...)

(1 4 9 16 25 36 49 64 ...)

(1 4 9 16 25 36 49 64 ... 576 625)

Page 22: Functional programming and ruby in functional style

22

Haskell :- [ x*x | x <- [1..10]]

Ruby :-(1..10).collect { |x| x*x}(1..10).map { |x| x*x}

=> [1,4,9,16,25,36,49,64,81, 100]

Page 23: Functional programming and ruby in functional style

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..]]]

Page 24: Functional programming and ruby in functional style

24

Lazy evaluation in Ruby 2.0

(0..Float::INFINITY).lazy.map { |x| 2*x }.take(5).to_a

#=> [0, 2, 4, 6, 8]

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.

Page 25: Functional programming and ruby in functional style

25

Example 2

What's the sum of the first 10 natural number whose square value is divisible by 5?

Page 26: Functional programming and ruby in functional style

26

Imperative

Ruby :n, num_elements, sum = 1, 0, 0while num_elements < 10 if n**2 % 5 == 0 sum += n num_elements += 1 end n += 1endsum #=> 275

Page 27: Functional programming and ruby in functional style

27

FunctionalRuby 2.0:Integer::natural.select { |x| x**2 % 5 == 0 }.take(10).inject(:+) #=> 275

Page 28: Functional programming and ruby in functional style

28

Ruby in a Functional style

Page 29: Functional programming and ruby in functional style

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

Page 30: Functional programming and ruby in functional style

30

Continued

message = if found_dog == our_dog "We found our dog #{found_dog.name}!"else "No luck"end

Page 31: Functional programming and ruby in functional style

31

Higher-order functions: map

output = [][1, 2, 3, 4].each do |x| output << x * 2endoutput # [2, 4, 6, 8]

output = [1, 2, 3, 4].map do |x| x * 2end # [2, 4, 6, 8]

Page 32: Functional programming and ruby in functional style

32

Higher-order functions: selectoutput = [][1, 2, 3, 4].each do |x| output << x if x > 2endoutput # [3, 4]

output = [1, 2, 3, 4].select do |x| x > 2end # [3, 4]

Page 33: Functional programming and ruby in functional style

33

Higher-order functions: detectoutput = nil[1, 2, 3, 4].each do |x| if x > 2 output = x break endendoutput # 3

output = [1, 2, 3, 4].detect do |x| x > 2end # 3

Page 34: Functional programming and ruby in functional style

34

Higher-order functions: inject/reduce

total = 0[1, 2, 3, 4].each do |x| total += xendtotal # 10

total = [1, 2, 3, 4].inject(0) do |acc, x| acc + xend # 10

For simple cases like this:total = [1, 2, 3, 4].inject(0, :+)

Page 35: Functional programming and ruby in functional style

35

Higher-order functions: zipx = [1, 2, 3]y = [:a, :b, :c]output = []0.upto(x.length - 1).each do |idx| output << [x[idx], y[idx]]endoutput #=> [[1, :a], [2, :b], [3, :c]]

x = [1, 2, 3]y = [:a, :b, :c]output = x.zip(y) #=> [[1, :a], [2, :b], [3, :c]]

Page 36: Functional programming and ruby in functional style

36

Take away

Let’s try to learn at least One “Functional” Language

and experience the power of functions !

Page 39: Functional programming and ruby in functional style

39

Thank you all for being patient and hearing me out.

Hope this helps you!