SlideShare a Scribd company logo
1 of 33
Download to read offline
Functional
Programming
is the most
Extreme
Programming
Intro
Extreme Programming (XP) was the precursor movement to Agile, it's focus was
primarily on simplicity of design, refactoring and maximising the amount of work
NOT done. This talk will introduce Functional Programming (FP) concepts and
compare them with Object/Class Oriented Programming (OOP). I will argue FP is
perfectly aligned to XP, while OOP typically has some shortcomings. I will even
argue that the entropy and complexity seen in most large scale projects is caused by
OOP rather than mitigated by it.
Preamble
- Please interrupt! Please disagree - helps me know what slides to stay on
- This talk is packed with a lot of concepts, you don’t need to follow it all
- Apologies for the lack of examples
Motivation
Enterprise FizzBuzz
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
Refuctoring
https://youtu.be/7RJmoCWx4cE?t=68
“OOP”?
Why do Functional Programmers home school their kids?
“OOP”?
Why do Functional Programmers home school their kids?
Because they hate Classes!
A Class is a scope where variables can be tied to functions and has a runtime
lifecycle.
Example
https://github.com/samthebest/dump/blob/master/sams-scala-tutorial/bad-code.cs
Go to bottom of
https://github.com/samthebest/dump/edit/master/sams-scala-tutorial/fp-4-newco
mers.md
Extreme Programming Recap
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take
away. —Antoine de Saint-Exupéry
Any intelligent fool can make things bigger, more complex and more violent. It takes a touch of
genius and a lot of courage to move in the opposite direction. —Albert Einstein.
When writing code, agile developers often stop to ask themselves, "What is the
simplest thing that could possibly work?" They seem to be obsessed with simplicity.
Rather than anticipating changes and providing extensibility hooks and plug-in points,
they create a simple design that anticipates as little as possible, as cleanly as
possible. Unintuitively, this results in designs that are ready for any change,
anticipated or not. -James Shore
https://www.jamesshore.com/Agile-Book/simple_design.html
Extreme Programming in 15 Chars
YAGNI
KISS
DRY
TDD
See also https://martinfowler.com/articles/designDead.html
Definition - Functional Programming
1. Things are functions <--- Mainly syntactic sugar
2. Functions are things <--- Mainly syntactic sugar
3. Functions are functions (huh?) <--- MOST IMPORTANT!!
4. Functions have no Free Variables
Things are Functions
You can apply most things in Scala as if they were a function, e.g.
scala> val mySet = Set(1, 3, 5, 6)
mySet: scala.collection.immutable.Set[Int] = Set(1, 3, 5, 6)
scala> mySet(4)
res0: Boolean = false
scala> mySet(5)
res2: Boolean = true
So mySet is a function from Int to Boolean, can you guess what it is?
Functions are Things
We can declare and pass functions around like things. E.g.
scala> val addOne = (i: Int) => i + 1
addOne: Int => Int = <function1>
scala> val list = List(1, 2, 2, 5, 5, 6)
list: List[Int] = List(1, 2, 2, 5, 5, 6)
scala> list.map(addOne)
res6: List[Int] = List(2, 3, 3, 6, 6, 7)
So Much Sugar
- Call objects as functions
- Pass functions around
-
- Currying
- Lamda (anonymous function) syntax
- Pattern matching - used for logic, and also dispatch (over poly’ based dispatch)
- Can use both postfix & infix (so can introduce operators as methods)
Functions are really Functions! AKA Pure
Functions
● That is they are functions in the formal mathematical sense
● They only take some parameters and return a result
I.e.
1. They do NOT change anything
2. They can NOT depend on change
(NOTE: Style and practice - not forced by the language.)
Breaks 1
scala> var iCanChange = 0
scala> def notReallyAFunction(bar: Int): Int = {
iCanChange = iCanChange + 10
bar
}
scala> notReallyAFunction(5)
res16: Int = 5
scala> iCanChange
res17: Int = 10
This is called a "side effect"
Breaks 2
scala> var iCanChange = 0
iCanChange: Int = 0
scala> def notReallyAFunction(bar: Int): Int = iCanChange + bar
notReallyAFunction: (bar: Int)Int
scala> notReallyAFunction(5)
res9: Int = 5
scala> iCanChange = iCanChange + 3
iCanChange: Int = 3
scala> notReallyAFunction(5)
res10: Int = 8
Pure Functions Are Important
A system's complexity is determined by the number of moving parts, the more
complex a system the harder it is to understand and consequently the more
mistakes will be made. Therefore having a system with no moving parts eliminates
almost all complexity and thus almost all mistakes.
NOTE: You can do functional programming in any language even if it doesn't
support the usual syntactic sugar.
Functions have no Free Variables
// In a class
public void BuildSQLConfig()
{
var sqlConfig = SqlConfigReader.ReadSQLConfig();
_config.SqlConnectionString = sqlConfig.ConnectionString;
}
After some refactoring
// In a (“static”) namespace
public BuildSQLConfig(config: Config, sqlConfigFile: String): Config
{
var sqlConfig = SqlConfigReader.ReadSQLConfig(sqlConfigFile);
config.copy(SqlConnectionString = sqlConfig.ConnectionString);
}
Point of OOP
1. Encapsulating Mutable State
○ No longer necessary (memory & cpu is cheap), can just “copy” rather
than mutate
2. Dynamic Dispatch via Inheritance Polymorphism
○ In FP we use instead:
i. Type-classes
ii. Dependencies that would normally need dynamic dispatch (e.g. calls to a DB, FS, etc)
are removed from the business logic and deferred via Monads & ADTs
○ Dynamic Dispatch via OOP still useful for external dependencies since (i) Type-classes can
leak type parameters, and (ii) deferred execution isn’t always an option
OOP (COP) vs FP - Principles
“OOP” employs SOLID, which are a set of mostly vague subjective principles to
prevent tight coupling. SRP can lead to Refuctoring (see video).
FP employs KISS, YAGNI, DRY and mathematical objectively defined concepts (e.g.
Monad, Monoid, etc)
KISS, YAGNI, DRY can be defined formally in terms of Complexity Theory, see
Kolmogorov Complexity, Agda, Idris, Code gen, etc
Intermission
Origins Of Coupling - Two Big Leaks!
1. Tying Data & Functions in a single scope.
This complicates scopes and means many methods have Free Variables, these Free
Variables tie methods together in such a way that is over and above the signature of
the method. This is a lexical LEAK.
2. Furthermore state couples methods together. This is a logical LEAK.
Without these leaks expressions become fully transparent - they do the exact same
thing no matter where they are in the codebase
Recommend reading First Order Logic and Complexity Theory (especially Kolmogorov), e.g. Mathematical Introduction to Logic & Introduction to
Mathematical Logic by Enderton & Mendelson resp
https://en.wikipedia.org/wiki/Free_variables_and_bound_variables
FP - No Tight Coupling
- Avoid classes (so avoid Free Variables in methods). Only use functions in static
namespaces and pass around structs (aka data containers, case classes)
- Avoid mutation
Now we observe:
- A function cannot couple via state
- A function cannot couple via scope, all dependencies of the function must be
passed in via the parameters
- Every function is a Single Responsibility (even if in the same file)
- Functions can be easily moved around and refactored
- Function can be easily tested (no need to new up a class with a billion
dependencies just to test 1 function in the class, and no `private`)
… FP - No Tight Coupling
- No need for complex inheritance hierarchies
- Barely ever even a need for interfaces
- Most applications can be built using a very simple set of languages features
(again think Lisp)
Connascence - Taxonomy of Coupling
Coupling of Meaning - (types help us here)
Coupling of Algorithm - (again, types)
Couple of Position - (named params helps, types help)
Coupling of Value - (DRY)
Coupling of Execution Order (can solve with FP, no state)
https://www.slideshare.net/carlosraffellini/connascence-136561891 and http://connascence.io/
Design Patterns (DP)
You don’t need Design Patterns either, yet another load of crap you don’t need to learn. E.g.
Please avoid Design Pattern terminology in Functional Languages
https://blog.jooq.org/2016/07/04/how-functional-programming-will-finally-do-away-with-the-gof-patterns/
https://stackoverflow.com/questions/327955/does-functional-programming-replace-gof-design-patterns
Factory Pattern Currying and returning functions
Decorators on streams Lazily evaluated iterators
Visitor pattern Pattern matching
Command pattern Functions as first class
Various ways to do dynamic dispatch Pattern matching
End of Tight Coupling - Types FTW!
SOLID simpler: FP & Types
Some forms of coupling will remain, but all these forms can be solved with good
Type design.
Most Functional languages provide very rich type features (see Dotty, Haskell,
Agda, Idris)
Type aliases mean we can even avoid coupling on type (where necessary!)
Microservices (MS)
There are two main motivations for Microservices
Handling Complexity in Large Applications
- “OOP” Monolithes are hard to understand, maintain, develop and test.
- Complexity in “OOP” Monolithes tends to grow quadratically in the number of features (every feature
ends up impacting development of every other feature)
- FP Monolithes grow in complexity linearly, so Micro Services provide no benefit, in fact they just add
engineering complexity
Concurrency & Deployment Granularity
- FP got here first (again!), see Erlang, Elixir, Akka, etc
In essence all Microservices do is force modules to only interact via messages/structs and to not leak state,
which is exactly what FP is. Finally, most devs do Microservices really badly (distributed monolith,
multi-repos, build hell, etc)
Common Counters / Misconceptions
A perfect “OOP” developer won’t
introduce coupling and hard to reverse
design smells
BUT!
- ~50% of devs have less than 5 years experience
- OOP, SOLID, Design Patterns, Micro Services etc
require training from considerably more senior devs
- Why make things complicated if a simpler alternative
exists?
- “Perfect” cannot be defined since SOLID, DP, MS etc is
subjectively defined
- Giving devs a huge list of “do’s” is much harder than a
very short list of “do nots”
FP results in long parameter lists Wrap params in more structs
FP means passing Contexts around over and over.
OOP has DI frameworks.
Scala offers implicit parameters for this. Some
people prefer explicit passing of contexts anyway
as there is no Hocus Pocus.
YAGNI
- SOLID
- Access modifiers (most of the time no state to protect)
- Design Patterns
- Micro Services (and probably not Azure Functions / AWS Lambda either)
- Multirepos (Monorepos FTW!)
- Dependency Injection Frameworks
- As many unit tests
- As many developers
- Fear of monolithes and large projects
FP is the most XP
Little to no up front design necessary, no SRP or SOLID.
Source of all complexity is the Two Big Leaks: Free Variables & State.
“OOP” encourages premature abstraction (unnecessary interfaces & hierarchies).
Premature abstractions are always wrong and leaky.
Simply write all code in functions and pass in all dependencies in the signature.
Use tests (TDD) & DRY to motivate splitting functions not SRP
Send Shout Outs
Shoutouts.asosapps.com
Scala Bonus - Inlining and Named Params
We often see
val fred = … some code …
val bob = … some code …
someFunction(fred, bob)
Please do instead
someFunction(
fred = … some code ...,
bob = … some code ...
)

More Related Content

What's hot

SparkApplicationDevMadeEasy_Spark_Summit_2015
SparkApplicationDevMadeEasy_Spark_Summit_2015SparkApplicationDevMadeEasy_Spark_Summit_2015
SparkApplicationDevMadeEasy_Spark_Summit_2015
Lance Co Ting Keh
 

What's hot (20)

Why Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldWhy Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data World
 
Semantic Integration with Apache Jena and Stanbol
Semantic Integration with Apache Jena and StanbolSemantic Integration with Apache Jena and Stanbol
Semantic Integration with Apache Jena and Stanbol
 
How Hadoop Revolutionized Data Warehousing at Yahoo and Facebook
How Hadoop Revolutionized Data Warehousing at Yahoo and FacebookHow Hadoop Revolutionized Data Warehousing at Yahoo and Facebook
How Hadoop Revolutionized Data Warehousing at Yahoo and Facebook
 
Apache Spark Fundamentals
Apache Spark FundamentalsApache Spark Fundamentals
Apache Spark Fundamentals
 
Big Data Processing with Spark and Scala
Big Data Processing with Spark and Scala Big Data Processing with Spark and Scala
Big Data Processing with Spark and Scala
 
Machine Learning by Example - Apache Spark
Machine Learning by Example - Apache SparkMachine Learning by Example - Apache Spark
Machine Learning by Example - Apache Spark
 
Big Data Developers Moscow Meetup 1 - sql on hadoop
Big Data Developers Moscow Meetup 1  - sql on hadoopBig Data Developers Moscow Meetup 1  - sql on hadoop
Big Data Developers Moscow Meetup 1 - sql on hadoop
 
Building a SIMD Supported Vectorized Native Engine for Spark SQL
Building a SIMD Supported Vectorized Native Engine for Spark SQLBuilding a SIMD Supported Vectorized Native Engine for Spark SQL
Building a SIMD Supported Vectorized Native Engine for Spark SQL
 
Sempala - Interactive SPARQL Query Processing on Hadoop
Sempala - Interactive SPARQL Query Processing on HadoopSempala - Interactive SPARQL Query Processing on Hadoop
Sempala - Interactive SPARQL Query Processing on Hadoop
 
IBM Spark Technology Center: Real-time Advanced Analytics and Machine Learnin...
IBM Spark Technology Center: Real-time Advanced Analytics and Machine Learnin...IBM Spark Technology Center: Real-time Advanced Analytics and Machine Learnin...
IBM Spark Technology Center: Real-time Advanced Analytics and Machine Learnin...
 
Spark Meetup Amsterdam - Dealing with Bad Actors in ETL, Databricks
Spark Meetup Amsterdam - Dealing with Bad Actors in ETL, DatabricksSpark Meetup Amsterdam - Dealing with Bad Actors in ETL, Databricks
Spark Meetup Amsterdam - Dealing with Bad Actors in ETL, Databricks
 
Introduction to Spark - DataFactZ
Introduction to Spark - DataFactZIntroduction to Spark - DataFactZ
Introduction to Spark - DataFactZ
 
SparkApplicationDevMadeEasy_Spark_Summit_2015
SparkApplicationDevMadeEasy_Spark_Summit_2015SparkApplicationDevMadeEasy_Spark_Summit_2015
SparkApplicationDevMadeEasy_Spark_Summit_2015
 
SQL on Hadoop in Taiwan
SQL on Hadoop in TaiwanSQL on Hadoop in Taiwan
SQL on Hadoop in Taiwan
 
Spark mhug2
Spark mhug2Spark mhug2
Spark mhug2
 
Scaling Up AI Research to Production with PyTorch and MLFlow
Scaling Up AI Research to Production with PyTorch and MLFlowScaling Up AI Research to Production with PyTorch and MLFlow
Scaling Up AI Research to Production with PyTorch and MLFlow
 
Hadoop
HadoopHadoop
Hadoop
 
Allyourbase
AllyourbaseAllyourbase
Allyourbase
 
Cloudera Impala Internals
Cloudera Impala InternalsCloudera Impala Internals
Cloudera Impala Internals
 
Apache Spark Streaming
Apache Spark StreamingApache Spark Streaming
Apache Spark Streaming
 

Similar to Functional programming is the most extreme programming

Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...
New York City College of Technology Computer Systems Technology Colloquium
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogramming
Luis Atencio
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
elliando dias
 

Similar to Functional programming is the most extreme programming (20)

Why Functional Programming So Hard?
Why Functional Programming So Hard?Why Functional Programming So Hard?
Why Functional Programming So Hard?
 
Fp for the oo programmer
Fp for the oo programmerFp for the oo programmer
Fp for the oo programmer
 
WHY JAVASCRIPT FUNCTIONAL PROGRAMMING IS SO HARD?
WHY JAVASCRIPT FUNCTIONAL PROGRAMMING IS SO HARD? WHY JAVASCRIPT FUNCTIONAL PROGRAMMING IS SO HARD?
WHY JAVASCRIPT FUNCTIONAL PROGRAMMING IS SO HARD?
 
Mastering Python lesson 4_functions_parameters_arguments
Mastering Python lesson 4_functions_parameters_argumentsMastering Python lesson 4_functions_parameters_arguments
Mastering Python lesson 4_functions_parameters_arguments
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
 
Why functional programming in C# & F#
Why functional programming in C# & F#Why functional programming in C# & F#
Why functional programming in C# & F#
 
Principled io in_scala_2019_distribution
Principled io in_scala_2019_distributionPrincipled io in_scala_2019_distribution
Principled io in_scala_2019_distribution
 
Javascript
JavascriptJavascript
Javascript
 
Functional Programming in Java
Functional Programming in JavaFunctional Programming in Java
Functional Programming in Java
 
Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...Towards Improving Interface Modularity in Legacy Java Software Through Automa...
Towards Improving Interface Modularity in Legacy Java Software Through Automa...
 
379008-rc217-functionalprogramming
379008-rc217-functionalprogramming379008-rc217-functionalprogramming
379008-rc217-functionalprogramming
 
Introduction to functional programming
Introduction to functional programmingIntroduction to functional programming
Introduction to functional programming
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
 
Designing function families and bundles with java's behaviors parameterisatio...
Designing function families and bundles with java's behaviors parameterisatio...Designing function families and bundles with java's behaviors parameterisatio...
Designing function families and bundles with java's behaviors parameterisatio...
 
GTU PHP Project Training Guidelines
GTU PHP Project Training GuidelinesGTU PHP Project Training Guidelines
GTU PHP Project Training Guidelines
 
Functional Programming In Jdk8
Functional Programming In Jdk8 Functional Programming In Jdk8
Functional Programming In Jdk8
 
Lambda Expressions in Java 8
Lambda Expressions in Java 8Lambda Expressions in Java 8
Lambda Expressions in Java 8
 
Oracle DBA interview_questions
Oracle DBA interview_questionsOracle DBA interview_questions
Oracle DBA interview_questions
 
10 things you're doing wrong in Talend
10 things you're doing wrong in Talend10 things you're doing wrong in Talend
10 things you're doing wrong in Talend
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Functional programming is the most extreme programming

  • 2. Intro Extreme Programming (XP) was the precursor movement to Agile, it's focus was primarily on simplicity of design, refactoring and maximising the amount of work NOT done. This talk will introduce Functional Programming (FP) concepts and compare them with Object/Class Oriented Programming (OOP). I will argue FP is perfectly aligned to XP, while OOP typically has some shortcomings. I will even argue that the entropy and complexity seen in most large scale projects is caused by OOP rather than mitigated by it.
  • 3. Preamble - Please interrupt! Please disagree - helps me know what slides to stay on - This talk is packed with a lot of concepts, you don’t need to follow it all - Apologies for the lack of examples
  • 5. “OOP”? Why do Functional Programmers home school their kids?
  • 6. “OOP”? Why do Functional Programmers home school their kids? Because they hate Classes! A Class is a scope where variables can be tied to functions and has a runtime lifecycle.
  • 7. Example https://github.com/samthebest/dump/blob/master/sams-scala-tutorial/bad-code.cs Go to bottom of https://github.com/samthebest/dump/edit/master/sams-scala-tutorial/fp-4-newco mers.md
  • 8. Extreme Programming Recap Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. —Antoine de Saint-Exupéry Any intelligent fool can make things bigger, more complex and more violent. It takes a touch of genius and a lot of courage to move in the opposite direction. —Albert Einstein. When writing code, agile developers often stop to ask themselves, "What is the simplest thing that could possibly work?" They seem to be obsessed with simplicity. Rather than anticipating changes and providing extensibility hooks and plug-in points, they create a simple design that anticipates as little as possible, as cleanly as possible. Unintuitively, this results in designs that are ready for any change, anticipated or not. -James Shore https://www.jamesshore.com/Agile-Book/simple_design.html
  • 9. Extreme Programming in 15 Chars YAGNI KISS DRY TDD See also https://martinfowler.com/articles/designDead.html
  • 10. Definition - Functional Programming 1. Things are functions <--- Mainly syntactic sugar 2. Functions are things <--- Mainly syntactic sugar 3. Functions are functions (huh?) <--- MOST IMPORTANT!! 4. Functions have no Free Variables
  • 11. Things are Functions You can apply most things in Scala as if they were a function, e.g. scala> val mySet = Set(1, 3, 5, 6) mySet: scala.collection.immutable.Set[Int] = Set(1, 3, 5, 6) scala> mySet(4) res0: Boolean = false scala> mySet(5) res2: Boolean = true So mySet is a function from Int to Boolean, can you guess what it is?
  • 12. Functions are Things We can declare and pass functions around like things. E.g. scala> val addOne = (i: Int) => i + 1 addOne: Int => Int = <function1> scala> val list = List(1, 2, 2, 5, 5, 6) list: List[Int] = List(1, 2, 2, 5, 5, 6) scala> list.map(addOne) res6: List[Int] = List(2, 3, 3, 6, 6, 7)
  • 13. So Much Sugar - Call objects as functions - Pass functions around - - Currying - Lamda (anonymous function) syntax - Pattern matching - used for logic, and also dispatch (over poly’ based dispatch) - Can use both postfix & infix (so can introduce operators as methods)
  • 14. Functions are really Functions! AKA Pure Functions ● That is they are functions in the formal mathematical sense ● They only take some parameters and return a result I.e. 1. They do NOT change anything 2. They can NOT depend on change (NOTE: Style and practice - not forced by the language.)
  • 15. Breaks 1 scala> var iCanChange = 0 scala> def notReallyAFunction(bar: Int): Int = { iCanChange = iCanChange + 10 bar } scala> notReallyAFunction(5) res16: Int = 5 scala> iCanChange res17: Int = 10 This is called a "side effect"
  • 16. Breaks 2 scala> var iCanChange = 0 iCanChange: Int = 0 scala> def notReallyAFunction(bar: Int): Int = iCanChange + bar notReallyAFunction: (bar: Int)Int scala> notReallyAFunction(5) res9: Int = 5 scala> iCanChange = iCanChange + 3 iCanChange: Int = 3 scala> notReallyAFunction(5) res10: Int = 8
  • 17. Pure Functions Are Important A system's complexity is determined by the number of moving parts, the more complex a system the harder it is to understand and consequently the more mistakes will be made. Therefore having a system with no moving parts eliminates almost all complexity and thus almost all mistakes. NOTE: You can do functional programming in any language even if it doesn't support the usual syntactic sugar.
  • 18. Functions have no Free Variables // In a class public void BuildSQLConfig() { var sqlConfig = SqlConfigReader.ReadSQLConfig(); _config.SqlConnectionString = sqlConfig.ConnectionString; } After some refactoring // In a (“static”) namespace public BuildSQLConfig(config: Config, sqlConfigFile: String): Config { var sqlConfig = SqlConfigReader.ReadSQLConfig(sqlConfigFile); config.copy(SqlConnectionString = sqlConfig.ConnectionString); }
  • 19. Point of OOP 1. Encapsulating Mutable State ○ No longer necessary (memory & cpu is cheap), can just “copy” rather than mutate 2. Dynamic Dispatch via Inheritance Polymorphism ○ In FP we use instead: i. Type-classes ii. Dependencies that would normally need dynamic dispatch (e.g. calls to a DB, FS, etc) are removed from the business logic and deferred via Monads & ADTs ○ Dynamic Dispatch via OOP still useful for external dependencies since (i) Type-classes can leak type parameters, and (ii) deferred execution isn’t always an option
  • 20. OOP (COP) vs FP - Principles “OOP” employs SOLID, which are a set of mostly vague subjective principles to prevent tight coupling. SRP can lead to Refuctoring (see video). FP employs KISS, YAGNI, DRY and mathematical objectively defined concepts (e.g. Monad, Monoid, etc) KISS, YAGNI, DRY can be defined formally in terms of Complexity Theory, see Kolmogorov Complexity, Agda, Idris, Code gen, etc
  • 22. Origins Of Coupling - Two Big Leaks! 1. Tying Data & Functions in a single scope. This complicates scopes and means many methods have Free Variables, these Free Variables tie methods together in such a way that is over and above the signature of the method. This is a lexical LEAK. 2. Furthermore state couples methods together. This is a logical LEAK. Without these leaks expressions become fully transparent - they do the exact same thing no matter where they are in the codebase Recommend reading First Order Logic and Complexity Theory (especially Kolmogorov), e.g. Mathematical Introduction to Logic & Introduction to Mathematical Logic by Enderton & Mendelson resp https://en.wikipedia.org/wiki/Free_variables_and_bound_variables
  • 23. FP - No Tight Coupling - Avoid classes (so avoid Free Variables in methods). Only use functions in static namespaces and pass around structs (aka data containers, case classes) - Avoid mutation Now we observe: - A function cannot couple via state - A function cannot couple via scope, all dependencies of the function must be passed in via the parameters - Every function is a Single Responsibility (even if in the same file) - Functions can be easily moved around and refactored - Function can be easily tested (no need to new up a class with a billion dependencies just to test 1 function in the class, and no `private`)
  • 24. … FP - No Tight Coupling - No need for complex inheritance hierarchies - Barely ever even a need for interfaces - Most applications can be built using a very simple set of languages features (again think Lisp)
  • 25. Connascence - Taxonomy of Coupling Coupling of Meaning - (types help us here) Coupling of Algorithm - (again, types) Couple of Position - (named params helps, types help) Coupling of Value - (DRY) Coupling of Execution Order (can solve with FP, no state) https://www.slideshare.net/carlosraffellini/connascence-136561891 and http://connascence.io/
  • 26. Design Patterns (DP) You don’t need Design Patterns either, yet another load of crap you don’t need to learn. E.g. Please avoid Design Pattern terminology in Functional Languages https://blog.jooq.org/2016/07/04/how-functional-programming-will-finally-do-away-with-the-gof-patterns/ https://stackoverflow.com/questions/327955/does-functional-programming-replace-gof-design-patterns Factory Pattern Currying and returning functions Decorators on streams Lazily evaluated iterators Visitor pattern Pattern matching Command pattern Functions as first class Various ways to do dynamic dispatch Pattern matching
  • 27. End of Tight Coupling - Types FTW! SOLID simpler: FP & Types Some forms of coupling will remain, but all these forms can be solved with good Type design. Most Functional languages provide very rich type features (see Dotty, Haskell, Agda, Idris) Type aliases mean we can even avoid coupling on type (where necessary!)
  • 28. Microservices (MS) There are two main motivations for Microservices Handling Complexity in Large Applications - “OOP” Monolithes are hard to understand, maintain, develop and test. - Complexity in “OOP” Monolithes tends to grow quadratically in the number of features (every feature ends up impacting development of every other feature) - FP Monolithes grow in complexity linearly, so Micro Services provide no benefit, in fact they just add engineering complexity Concurrency & Deployment Granularity - FP got here first (again!), see Erlang, Elixir, Akka, etc In essence all Microservices do is force modules to only interact via messages/structs and to not leak state, which is exactly what FP is. Finally, most devs do Microservices really badly (distributed monolith, multi-repos, build hell, etc)
  • 29. Common Counters / Misconceptions A perfect “OOP” developer won’t introduce coupling and hard to reverse design smells BUT! - ~50% of devs have less than 5 years experience - OOP, SOLID, Design Patterns, Micro Services etc require training from considerably more senior devs - Why make things complicated if a simpler alternative exists? - “Perfect” cannot be defined since SOLID, DP, MS etc is subjectively defined - Giving devs a huge list of “do’s” is much harder than a very short list of “do nots” FP results in long parameter lists Wrap params in more structs FP means passing Contexts around over and over. OOP has DI frameworks. Scala offers implicit parameters for this. Some people prefer explicit passing of contexts anyway as there is no Hocus Pocus.
  • 30. YAGNI - SOLID - Access modifiers (most of the time no state to protect) - Design Patterns - Micro Services (and probably not Azure Functions / AWS Lambda either) - Multirepos (Monorepos FTW!) - Dependency Injection Frameworks - As many unit tests - As many developers - Fear of monolithes and large projects
  • 31. FP is the most XP Little to no up front design necessary, no SRP or SOLID. Source of all complexity is the Two Big Leaks: Free Variables & State. “OOP” encourages premature abstraction (unnecessary interfaces & hierarchies). Premature abstractions are always wrong and leaky. Simply write all code in functions and pass in all dependencies in the signature. Use tests (TDD) & DRY to motivate splitting functions not SRP
  • 33. Scala Bonus - Inlining and Named Params We often see val fred = … some code … val bob = … some code … someFunction(fred, bob) Please do instead someFunction( fred = … some code ..., bob = … some code ... )