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 ?