how functional programming made me a better developer
TRANSCRIPT
How Functional Programming Made Me A Better DeveloperCameron Presley@PCameronPresleyhttp://blog.TheSoftwareMentor.com
Thank The Sponsors!
Little About Me
From Knoxville, TN
Software Engineer at Pilot Flying J
Musician, board gamer, and mentor
Co-organizer of FunctionalKnox
Outline
The Journey of Learning Functional Programming
How My Style Has Evolved
How I Think About Software
Resources
The Journey
Link
Some SOLID Inspiration
Mnemonic for software design coined by Robert C. Martin
By following SOLID, we tend to write more maintainable code
Teach and present on SOLID a lot
Want to focus on the Single Responsibility Principle
Some SOLID Inspiration
“The single responsibility principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.”
-Wikipedia
Some SOLID Interpretation
What happens if you follow Single Responsibility to the extreme?
Lots of small classes with a single method
Felt like a lot of ceremony
Asking the Twitterverse
Twitter Responds!
Seems Like I Wasn’t The First With This Idea…
http://blog.ploeh.dk/2014/03/10/solid-the-next-step-is-functional/
Mark’s Thoughts
Extreme SRP and ISP, leads to a lot of fine grain classes
An object can be thought of data with behavior
What if we flipped that concept around? Behavior with data
Sounds like a functional approach to the problem
Time to Learn Functional
Chose F#
Familiar with the .NET framework
Comfortable with the .NET tooling
Community resources
First Attempt
Premise
Decided to port a C# application (Task Snapper) Grabs a screenshot every so often
Focus on the language, not the problem
Dipping my toes into FP
Implementation
Reflection
It’s F#!
Wrote object-oriented in a functional language Definitely not idiomatic
Didn’t really see the point
Need to learn more about functional
Second Attempt
Premise
Found out that card games tend to be a great exercise
Want to use Love Letter as an example card game 8 different kinds of cards, each with their own special rules
Write more idiomatic functional No classes, no exceptions
Implementation
Reflection
No exceptions!
Learning more about data modeling Making illegal state unrepresentable
Game rules a bit more complicated than expected Spending a lot of time learning the problem, not solving the problem
Third Attempt
Premise
Modeling a card game still makes sense
Something with easier business rules Able to solve a real problem without getting lost
Decided on Blackjack Just enough business rules to do something
Making Illegal States Unrepresentable
Business Rules for How Many Pointsa Card Is Worth
Business Rules For Adding Points Together
Calculating How Many Points ForA Hand
Reflection
Comfortable with handling errors without exceptions
Using pattern matching more effectively
Working with built-in List operators Map and Reduce
Starting to think about how to use these concepts in C#
At the End
Worked on/off over the course of the year
Got frustrated at times
Spent time learning, asking questions on Twitter, StackOverflow
Didn’t give up
Starting to think about these concepts in OOP
Writing Testable Code
Why Write Testable Code?
If code is easy to test, it’s usually easy to maintain
Implies that hard to test code may not be maintainable
What defines easy to test code?
A Hypothetical
Pretend we were writing tests around a particular method. Which one would you rather test?
A) A method that when given the same two inputs, it returns the same output
B) A method that when given the same two inputs, it returns different outputs
Thinking About Testability
If a method always returns output solely based on inputs, we call that method pure. No side effects or state involved
Easiest types of test to write No mocking, no fake implementations to use
Frameworks that use this concept Reducers (Redux) Elm architecture
Improved LINQ
Typical Approach
When working with a list of data, I’d typically work with a for each loop.
A Different Approach
In functional programming, typically work with multiples of data as lists Typically use built-in list functions (map, filter)
Leveraging LINQ
Instead of Map and Filter, LINQ uses Select and Where
Useful Interfaces
How I Used Interfaces
What Is an Interface
It’s a guarantee that a method with that signature exists
Essentially a contract
If the contract is not fulfilled, the compiler tells you
Allows us to use the compiler to find errors “Leaning on the compiler”
Pop Quiz!
Given this interface, what should GetById return?
Anything that implements this interface will always return a Record object, right?
How about this implementation?
Interfaces That Don’t Lie
Interface says that a Record will always be returned
If I handle the Record, then the compiler is happy
However, the compiler can’t enforce that I handled the null condition
Likely for me to introduce bugs into the system
The Functional Approach
No concept of null, typically use something called Option or Maybe
Has two values, either Some<‘a> or None
The Functional Approach
If a function returns an Option, callers must deal with it.
Otherwise, code fails to compile
How My Style Evolved
Using purity to make business rules testable
Reducing complexity by leveraging LINQ
Think more about types and interfaces
How I Think About Software
Types of Components
Boundary How data comes in or goes out of the system
Business Rule How to work with data for our business needs
Workflows Combines both boundary and business rule components
Boundary Components
Anything that deals with getting data in/out of a system is a boundary
Examples include databases, servers, file system, user input, etc.
Makes sense to have these components implement an interface for testability
Inspired by Hexagonal Architecture by Alistair Cockburn
Getting Data In
Getting Data Out
Business Rule Components
Contain the rules for our application
Will make up the bulk of your application
Remember SOLID principles while implementing
For testability, purity is key
Business Rules
Workflow Components
Combines both Boundary and Business Rule components
Can be described as Data comes in through the boundary Data is processed by the business rules Data goes out through the boundary
Bringing It All Together
Bringing It All Together
Bringing It All Together
Bringing It All Together
Wrapping Up
Learning functional was hard for me Lots of failures, but improved incrementally
Made me re-evaluate how I build software
Still use functional concepts in my coding Even if I’m not using a functional language
Resources
F Sharp for Fun and Profit (https://fsharpforfunandprofit.com)
The Book of F#: Breaking Free with Managed Functional Programming by Dave Fancher
F# Jumpstart (Pluralsight Course) by Kit Eason
Mark Seemann’s blog: (http://blog.ploeh.dk)
Hexagonal Architecture (post) by Alistair Cockburn