MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
Lessons learned from functional programming
1. FP in OOP
Lessons learned from Functional Programming applied
to Object Oriented Programming
2. Functional Programming: Why?
OOP was the great paradigm shift of the 90s
FP will be the next great paradigm shift
Excels at parallel and distributed computing
3. Background: Church-Turing Thesis
Anything that could possibly be computed, can
be computed using any of the following:
● A Turing machine
● The Lambda Calculus
● Recursion
See Google for more details!
4. /* Factorial in PHP */
function factorial($n)
{
$result = 1;
for ($c = 1; $c <= $n; $c++)
$result = $result * $c;
return $result;
}
The Imperative Way
5. The Functional Way
-- Factorial in Haskell
factorial 0 = 1
factorial n = n * factorial (n - 1)
8. Value Objects
class Date {
private $day, $month, $year;
public function __construct($day, $month, $year) { ... }
public function isAfter(Date $other) { ... }
public function isBefore(Date $other) { ... }
public function isSame(Date $other) { ... }
}
class DateRange {
private $start, $end;
public function __construct(Date $start, Date $end) {
if ($start->isAfter($end)) {
throw new InvalidArgumentException(); }
}
public function contains(Date $day) {
return $day->isAfter($this->start) &&
$day->isBefore($this->end);
}}
10. Command/query separation
Isolates state-modifying logic
Queries are safe to reorder, easier to
optimize
Easier to test
Provides opportunity to use different
models for read and write operations
(CQRS)
11. Command/query separation
class ShoppingCart {
private $total = 0;
private $products = array();
public function calculateSubtotal() {
$subtotal = 0;
foreach ($this->products as $product) {
$subtotal += $product->getPrice();
}
return $subtotal;
}
public function calculateTax() {
return $this->total * 0.075;
}
public function addProduct($product) {
$this->products[] = $product;
}
public function updateTotal($amount) { $this->total = $amount;
14. Higher-order functions
Let you parameterize behavior or
designate new behavior at runtime
OOP design patterns:
● Strategy pattern
● Visitor pattern
15. Strategy Example - PHP 1
abstract class PricingStrategy {
private $customer;
public function __construct($customer) { ... }
abstract public function calculatePrice($prodcut);
}
class GoldClubPricing extends PricingStrategy {
public function calculatePrice($prodcut) { ... }
}
class HighRiskPricing extends PricingStrategy {
public function calculatePrice($prodcut) { ... }
}
class LoyalCustomerPricing extends PricingStrategy {
public function calculatePrice($prodcut) { ... }
}
16. Strategy Example - PHP 2
class ShoppingCart {
private $products;
private $customer;
private function getPricingStrategy($customer) { ... }
public function calculateSubtotal() {
$subtotal = 0;
$pricingStrategy = $this->getPricingStrategy($this->customer);
foreach ($this->products as $product) {
$subtotal += $pricingStrategy->calculatePrice($product);
}
return $subtotal;
}
}
21. Further Reading
Patterns of Enterprise Application Architecture -
Martin Fowler
Domain Driven Design - Eric Evans
A Functional Pattern System for Object-Oriented
Design - Thomas Kuhne
The Power of Value - Dan Johnsson
http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson
Objects, Anomalies, and Actors: The Next Revolution
http://www.infoq.com/presentations/Objects-Anomalies-and-Actors-The-Next-Revolution
Actor Model Concurrency - Jeff Darcy
http://pl.atyp.us/wordpress/index.php/2009/07/actor-model-concurrency
Editor's Notes
Welcome to ioXchange!
Lead with title
Slide first
OOP is still the dominant paradigm
FP makes it easier to deal with concurrent and distributed systems reliably
Touch on some of the reasons why in this presentation
Object Anomalies presentation linked at end
Slide first
All three are equivalent
Turing machines work by modifying state and recording on tape
Lambda Calculus/Recursion work by deriving state from expression evaluation
Notes first
PHP's syntax close enough to C so most people can follow it
Explain slide
Special case of factorial(0) is handled by side effect of for loop condition failing on the first iteration
Typical FP: recursion instead of iteration
Tail-call optimization used
Came from SmallTalk community?
Slide first
Strings, Tuples, or other small values provided by the language
Date business logic methods
DateRange invariant enforced through Date methods
DateRange composed of Date value objects
Immutable - No access to change object state
Safe to compose, re-order, pass around
The Turing model can be dangerous sometimes
Separates logic into commands and queries
Queries - side effect free functions
Commands - modify observable state, but don't return anything
Explain slide
Testing needs different approaches for commands vs queries
Commands usually need more fixture setup
Can be applied architecturally to extend benefits to whole system (Greg Young, CQRS)
3 queries, 2 commands
Requires language to support functions as first-class values
Explain slide
Concrete Strategy implementations derived from an abstract base class defining the common interface
The shopping cart picks which pricing strategy to apply based on who its customer is
The pricing strategy is then used to calculate the adjusted price for each product in the shopping cart
The adjusted prices are added up to produce the cart subtotal
Slide First - brief; explain syntax after
Higher order
map takes a function value as an argument
getPricingStrategy returns functions as first class values
Shipping costs can be treated the same way
Each point, one at a time
Lazy Evaluation
Defer evaluation until you really need the value
Pulling rows from a result set
Map/Reduce (Folds)
One of the main ways to avoid iteration, besides recursion
Stats over a list, string tokenization
Testability/Composability of iterators, but can be distributed and/or parallelized - Hadoop
Message passing
Contrasts with shared-state concurrency
Shared-state concurrency relies on locking and is easy to get wrong - deadlocks, lock releasing
Simple mailbox metaphor, no shared state
Local or remote, unlike shared-state
Actor model
Based on message passing, popularized by Erlang
Processes that own the state, local or remote
Valid messages form a protocol, little state machines
FP techniques make systems:
More scalable
Easier to test/debug
More future-proof