Functional programming and ruby in functional style

Post on 15-Jan-2015

829 views 2 download

Tags:

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 !

Transcript of Functional programming and ruby in functional style

1

Functional Programming (FP) &

Ruby in Functional style

- Niranjan Sarade

2

Agenda

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

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

4

Perils of Mutable state

• Mutable state

– Leads to more bugs

– Makes concurrency quite difficult

– Shared mutability

5

What’s Old is New again!

6

y = f(x)

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

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

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.

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.

11

Continued

• Lisp is used for artificial intelligence applications.

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

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

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

14

Immutability / No side effect

Higher order Functions

Functional Style

Ruby GroovyPython

SmalltalkClojure

Scala

Purely Functional

HaskellErlang

Lisp

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'

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

17

Memoization

18

Without memoize

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

fib(35) # slow

#2.879s

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

20

Example 1

Squares of Integers

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)

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]

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

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.

25

Example 2

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

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

27

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

28

Ruby in a 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

30

Continued

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

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]

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]

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

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, :+)

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

36

Take away

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

and experience the power of functions !

39

Thank you all for being patient and hearing me out.

Hope this helps you!