On Github bjoska / functional_programming_in_an_object_oriented_world
f(x)
fn(x) = x * 25 / 100
function fn(x) {
return x * 25 / 100;
}
(Javascript)
def add_to_shopping_cart(item) self.items << item self.total += item.value self.total end
(Ruby)
def add_to_shopping_cart(item)
self.items << item
end
def total
sum = 0
for item in items do
sum += item.value
end
sum
end
(Ruby)
def add_to_shopping_cart(item)
self.items << item
log("Item added to cart: #{item.sku}")
end
(Ruby)
class Invoice < ActiveRecord::Base # ORM class
belongs_to :customer
def issue
customer.add_amount(self.amount)
self.status = 'Issued'
customer.total
end
end
(Ruby)
class Customer < ActiveRecord::Base
has_many :invoices
def total_amount
invoices.where(status: 'Issued').reduce(0) do |total, invoice|
total += invoice.amount
total
end
end
end
class Invoice < ActiveRecord::Base
belongs_to :customer
def issue
self.status = 'Issued'
end
end
(Ruby)
So we fixed the side effects, but at what cost?
"We can handle latency as we do in life." - Aslam Khan
def add_to_shopping_cart(item) self.items << item self.items end
(Ruby)
def add_item_to_shopping_cart(shopping_cart, item) shopping_cart.add item shopping_cart end
(Ruby)
def add_item_to_shopping_cart(shopping_cart, item) # Dirty hack to deep copy an object in Ruby shopping_cart = Marshal.load(Marshal.dump(shopping_cart)) shopping_cart.add item shopping_cart end
(Ruby)
next_value() {
this.n += 1;
return this.n;
}
(Javascript)
next_value(current_int) {
return current_int + 1;
}
(Javascript)
Blowing the stack
Tail Call Optimisation
function sum(numbers) {
if(numbers.length == 0) {
return 0;
}
return numbers[0] + sum(numbers.slice(1));
}
(Javascript)
function sum(acc, numbers) {
if(numbers.length == 0) {
return acc;
}
return sum(acc + numbers[0], numbers.slice(1));
}
(Javascript)
Functions that take functions
function sum(acc, numbers) {
if(numbers.length == 0) {
return acc;
}
return sum(acc + numbers[0], numbers.slice(1));
}
(Javascript)
function reduce(acc, collection, fn) {
if(collection.length == 0) {
return acc;
}
return reduce(fn(acc, collection[0]), collection.slice(1), fn);
}
function sum(numbers) {
return reduce(0, numbers, function(a, b) {
return a + b;
});
}
function count(numbers) {
return reduce(0, numbers, function(a, _) {
return a + 1;
});
}
(Javascript)