for an Imperative Mind
Rajeev N B
Application Developer
RubyConf India 2015
Functional Programming is unfamiliar territory for most,
If you want everything to be familiar you will never learn anything new
- Rich Hickey (Author of Clojure and Datomic)
- John Hughes , Why Functional Programming Matters
(f o g)
 # => g(x) = x * 1
 g = -> (x) { x + 1 } 
 # => f(x) = x * x
 f = -> (x) { x * x }
 # Function composition => g(f(x)
 fg = -> (x) {  f[g[x]] }
 # call 
 fg[3]
 # => 16
 -- g(x) = x + 1
 g :: (Num a) => a -> a
 g x =  x + 1
 -- f(x) = x * x
 f :: (Num a) => a -> a
 f x = x * x
 -- Composite function g(f(x)
 gf = f . g
- Haskell Wiki
  # Strict Evaluation 
  [1, 2, 3/0, 4].length
  # => ZeroDivisionError: divided by 0
  # Simulate Lazy Evaluation with Lambdas
  [1, 2, -> { 3/0 }, 4].length
  # => 4
 # Infinite range ( Generator )
 range = 1..Float::INFINITY
 # Non Lazy will run forever
 range.collect { |val| val * val }.take(10).to_a
 # Lazy
 range.lazy.collect { |val| val * val }.take(10).to_a
 # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 -- Infinite generator
 range = [1..]
 -- Square function
 square :: ( Num a ) => a -> a
 square x = x * x
 result = take 10 (map square range)
 -- => [1,4,9,16,25,36,49,64,81,100]
- Alan Perlis
 def double(x)
   x * x
 end
 # map higher order function 
 #
 Array(1..10).map { |a| double(a) }
 # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 # Function returning function
 #
 def functionReturn
   -> (x) { x * x }
 end
 double :: ( Num a ) => a -> a
 double x = x * 2
 -- map takes double as argument
 -- function taking function as argument
 higher_order_function = map double [1..10]
 -- => [2,4,6,8,10,12,14,16,18,20]
 -- Function returning function as return value
 functionReturn :: ( Num a ) => (a -> a)
 functionReturn = \x -> x * x
 # Currying one argument at a time
 # Partial application of arguments
 add = proc { |x, y, z| x + y + z }
 add5 = add.curry.call(5)
 # equal to add.curry.call(5).call(6)
 add5and6 = add5.call(6)
 add5and6.call(10)  # => 21
 -- In Haskell functions always take a single argument
 -- Partial application of arguments
 -- Currying
 add :: Int -> Int -> Int
 add x y = x + y
- Wikipedia
# Recursion in Ruby
 def summify(list)
   return 0 if list.empty?
   element, *rest = list
   element + summify(rest)
 end
 summify :: ( Num a ) => [a] -> a
 -- summify calling itself
 summify [] = 0
 summify [x] = x 
 summify (x:xs) = x + summify xs 
vs
Functional
total = 0
i = 0
while i <= 10
  total += i
  i = i + 1
end
total 
total = (1..10).inject(:+)"Imperative programming is like giving instructions to an idiot."
"Functional programming is like describing your problem to a mathematician"
Why Functional Programming Matters ?