2. vpTech, the Veepee Tech Community
F#
Introducing a new language to the team?
The Team
■ Smart .NET Developers; between 3 and 19 years of experience
■ We enjoy writing clear and maintainable code
■ But… to get things right, C# often appeared to us as overly verbose
The Requirements
■ Built-in Functional capabilities
■ Low ceremony for Domain Modeling and logic impl.
■ Interoperability with .NET libraries
We couldn’t afford wasting time re-inventing the wheel (e.g. IO)
2
3. vpTech, the Veepee Tech Community
F#
Disclaimer
3
In this talk, there is NO:
■ Functional Programming Evenlangism Fairy Tales
■ Monads, Lenses, Applicatives and FP aficionados vocabulary
■ Category Theory Mumbo Jumbo
■ “F# is a Swiss Army knife that can make coffee”
■ “This is a complete F# training session”
100% PRACTICAL STUFF
4. vpTech, the Veepee Tech Community
■ Been around for about 18 years
■ Same SDKs as C#
■ Same frameworks as C#
■ Same Docker images as C#
■ Same commands as C# (dotnet test, build, etc)
■ Same tools as C# (VS, VSCode, Rider, etc)
■ Can consume any C# library
Lot of C# going on here…
Pssst, Spoiler Alert! .NET is NOT (only) C#!
F#
Another C#?
4
5. vpTech, the Veepee Tech Community
F#
The Common Language Infrastructure: rings a bell?
5
F# Code
C# Code
VB.NET
Code
F#
Compiler
C#
Compiler
VB.NET
Compiler
IL Code
Common
Language
Runtime
Machine
Code
Compile
Just-In-Time
Generate
F#, C#, VB.NET, Klingon.NET, etc.
=> At this stage, it doesn’t really matter anymore
Read by
Read by
6. vpTech, the Veepee Tech Community6
Hey but both F# and C# are .NET multi-paradigm programming languages…
So what’s the catch here?
■ F# is a functional-first language
■ C# is an OO-first language
F#
How does it differ from C#?
The programming language continuum
=> a spectrum of paradigms
7. vpTech, the Veepee Tech Community
F#
How does it really differ from C#?
7
Sorry guys, but still can’t really see the difference…
I mean, methods are also functions, right?
■ In F#, the main construct is a function
Often pure and dealing with immutable data
■ In C#, the main construct is an object
Often mutable and carrying both:
■ Behaviours (i.e. methods)
■ Data (i.e. themselves other objects which in turn
may also be mutable, etc.)
8. vpTech, the Veepee Tech Community
F#
“TALK IS CHEAP. SHOW ME THE CODE!!!”
8
A quote from your good friend
Linus Torvald:
9. vpTech, the Veepee Tech Community
F#
Collections: Lists
■ Built-in F# lists are immutable
■ Low ceremony
■ Functions are separated from data
■ Functions are in a dedicated module
■ Does not leverage (doubly) LinkedList<T>
=> dedicated implementation for F# (singly)
■ O(1) for prepending
■ O(n) for searching, deleting and appending
■ => Tradeoff immutability / complexity
“List” is a module here
10. vpTech, the Veepee Tech Community
F#
Collections: Sets and Maps
■ Built-in F# alternatives to traditional .NET
Set<T> and Dictionary<TKey, TValue>
■ Low ceremony and immutable
■ Functions are again separated from data
■ Both implemented as immutable AVL trees
■ Search, insert, and delete are all O(log n)
=> Again tradeoff (immutability / complexity)
“Set” and “Map” are also modules
11. vpTech, the Veepee Tech Community
F#
Collections: .NET Data Structures Interop
■ Built-in F# aliases for T[] and IEnumerable<T>
■ Arrays in F# are mutable (still just an alias)
■ As mentioned earlier you can use everything from
.NET even “old-fashioned” List<T>
■ In-place mutations are possible with “<-”
But not recommended when you’re starting
Worth looking at when optimizing
■ Array and Seq are dedicated modules
Functions in those, are mostly functional wrappers
12. vpTech, the Veepee Tech Community
F#
Records: AND-ing Types
12
NO
YES
■ Low ceremony type definition and instantiation
■ No methods (no behaviour)
■ Immutable by default
■ Can be parametrized with generics
■ Simple flat types are strongly recommended
Side note: “let” is how we define variables (and functions)
13. vpTech, the Veepee Tech Community
F#
Records: the F# Compiler is your friend
13
■ No default value when creating an instance
■ => Everything is explicit
■ Add a field and the compiler will make sure that you get the memo!
■ => Won’t compile
14. vpTech, the Veepee Tech Community
F#
Records: the F# Compiler is your real good friend
14
■ Structural equality, i.e. immutability and no hidden voodoo behaviour
■ Will print “false”
■ Will print “true”
Side note
In F# “=” is either for:
■ Assignation
■ Equality comparison (and not “==” like in C#)
15. vpTech, the Veepee Tech Community
F#
Records: the F# Compiler is your bestie!
15
Translates to an equivalent of 223 lines of C# code…
■ Immutability is not granted by default in IL / C#
■ Structural Equality in C# other than with structs is
also not granted by default
■ It has to be implemented through read-only
getters and and other strategies
It had to be cut at
about one fifth!
16. vpTech, the Veepee Tech Community
F#
Discriminated Unions: OR-ing Types
16
■ Not a C# enum, each case can be of any type
■ Just like records: low ceremony type definition and instantiation, and structural equality
■ An instance carries one of the cases (also called “choices”)
■ Again, no behaviour embedded in the type definition
■ Can also be parametrized with generics
17. vpTech, the Veepee Tech Community
F#
Pattern Matching
17
■ Powerful feature to avoid dirty branching
■ Building blocks of many validation and
mapping functions and operators
■ More versatile than its C# (8.0) counterpart
=> works on pretty much everything
■ Supports conditional matches too!
18. vpTech, the Veepee Tech Community
F#
And finally… Functions!
■ Low ceremony: type inference
■ Feels like writing Python… with actual Type safety!!!
■ Composition is a built in-operator ”>>”
■ Every function returns something, even “nothing”
=> “nothing” is actually a type called unit
=> unit has only one “value” possible ()
=> void methods in C# don’t return anything
■ You can still specify types if you need to:
18
Function Signature:
Param 1 Type -> Param 2 Type -> … -> Return Type
19. vpTech, the Veepee Tech Community
F#
Functions are A-MA-ZING!
19
■ You can create your own binary
operators
■ Functions are generally gathered
under modules
■ Functions also support access
modifiers
■ Just like in JavaScript, Partial
Application is also supported in F#
20. vpTech, the Veepee Tech Community
F#
More Functions for Validation => Example
20
■ You can use powerful validation
binary operators from well-known
F# libraries such as FSharpPlus
■ Let’s say we want to valid an unvalidated
person with the types below:
21. vpTech, the Veepee Tech Community
F#
Compose Functions for Even More Validations!
21
■ Considering those validation blocks,
we can then compose them to
validate a whole record type:
22. vpTech, the Veepee Tech Community
F#
A word about purity and (im)mutability
22
FunctionInput Output
Does the output rely exclusively on the given input?
What are the conditions to make that happen?
=> A pure function and immutable input(s)
23. vpTech, the Veepee Tech Community
F#
Pure Function: a dummy example
23
Immutability guarantees that the number is not
gonna be changed change while it is multiplied
=> Easier to reason and maintain
=> Deterministic
=> Parallel-friendly
2 x NumberNumber Output
Usually, immutable stuff
24. vpTech, the Veepee Tech Community
C#
OO: Typical DI effectful functions
24
Usually, mutable stuff
Controller
Repository
Validator
POST account
Create
Account
Request
Output
201, 400, 422 and whatnot
Oh that’s good cause we’re
decoupling responsibilities, right?
25. vpTech, the Veepee Tech Community
C#
OO: Always going even further
25
Controller
Provider
POST account
Provider
Repository
Validator
Piece of logic
that was before
in the controller
implementation
Still usually, mutable stuff
Create
Account
Request
Output
Still 201, 400, 422 and whatnot
26. vpTech, the Veepee Tech Community
C#
OO: To infinity and beyond!
26
Controller
Mediator
POST account
Provider
Repository
Command Handler
=> When the OO decoupling holy grail is getting highly questionable
=> Can lead to a pretty heavy cognitive load!
Validator
Create
Account
Request
Provider
Domain
Piece of logic
that used to be in
the controller
Implementation,
a long time ago
Related Domain
Output
27. vpTech, the Veepee Tech Community
F#
Life isn’t always rosy
27
The world is a twisted and dirty place...
Domain
Application
Infrastructure
Good old hex(agonal) architecture to the rescue!
IO
■ Domain: side effects free, pure functions only
■ Application: effects via function composition
■ Infrastructure: IO and .NET Framework interop libs
28. vpTech, the Veepee Tech Community
F#
How we practiced hex arch (a simplified version)
28
Business : Weather Data Provider
■ PO : Hey guys, I have two news.
Should I start with the bad one or the good one?!
■ Devs : Hmm...
■ PO : Let’s start with the good one then, we just signed a deal
to expose an API for a large American website.
■ PO : And the bad one, our temperatures are only in Celsius.
■ Devs : Oh F#word...
29. vpTech, the Veepee Tech Community29
F#
1. Domain Layer
■ Always start with the
domain layer
■ Small
Pure
Well unit-tested
Functions
with no Side Effects
Ehouarn is starting to code
Some cool stuff
Not only just for kicks
30. vpTech, the Veepee Tech Community30
F#
2. Application Layer
Ehouarn keeps coding and he doesn’t
need to care much about infrastructure
“Dependency Injection”: the FP way
31. vpTech, the Veepee Tech Community31
F#
3. Infrastructure Layer Amin is now taking over
Luckily for him, the fetch function is already there!
Need some refactoring here
=> Domain was leaked into DB
Oh, a higher order function!
But the signature
isn’t the same as the
application layer
32. vpTech, the Veepee Tech Community32
F#
4. API Layer (Program Entry Point) Sadly, Amin is running out of luck.
That being said, he IS smart!
Take the connection and
compose a new function.
Then use it as a "DI” function
33. vpTech, the Veepee Tech Community
Member Refund
Actual F# code used in Production: Validation
33
■ Validations used when creating
EDI Documents
■ Functions compositions
34. vpTech, the Veepee Tech Community
Member Refund
Actual F# code used in Production: Pipeline
34
■ A practical example of Railway
programing for AspNetCore
WebApi integration tests
■ You can “almost” read it as simple
English
35. vpTech, the Veepee Tech Community
F#rom the Trenches
Dos and Don’ts
35
■ Don’t use classes
■ Don’t use mutable variables
■ While developing, refrain yourself from using the debugger
Remember the compiler is your (strict) friend
■ Don’t leverage the OO mindset. It is your worst enemy!
■ Don’t mix IO stuff everywhere!
Isolate and them put at the end of the project then use functional DI
… except when you have to rely on a .NET OO C# based library
… or when you “need” some nitpicking optimizations
Don’t try to write C#code with F#!!!
36. vpTech, the Veepee Tech Community
F#rom the Trenches
Dos and Don’ts
36
■ Use Composition, it is the foundation of functional design:
■ Build new functions from smaller functions
■ Build new types from smaller types
■ Use FSharpPlus operators (<!>, <*> and many others)
■ Get rid of primitive obsession with wrapping types
■ Use Railway Oriented Programming (except for panic errors)
■ No need for OO Design Pattern shenanigans
■ Only a very few Haskell programming concepts might come in handy
=> only for advanced F# programmers
37. vpTech, the Veepee Tech Community
F# Key Takeaways
Pros and Cons
■ Smaller community than C#
■ There aren’t always functional wrappers for
well-known .NET OO designed libraries
■ Official guidelines don’t cover everything
=> You often have to come up with your own stuff
■ Multi-paradigm trap: it’s a bit too easy to fall into
the “I code the same way as in C#”
=> Often result in some kind of ugly code
■ Immutability for parallelism is a bit “overrated”
37
38. vpTech, the Veepee Tech Community
F# Key Takeaways
Pros and Cons
38
■ The community is really keen to help!
=> Overall less “pedantic” and dogmatic than in C#
■ Keep being productive with the whole .NET ecosystem
■ Coding your Domain in F# feels safe!
■ Learning curve is not that steep with proper guidance
■ F# code is expressive and concise while retaining type safety
■ It feels ugly to code the “C# way”, so you don’t get to do that for too long
=> The team is delighted! The adoption is 100% real!
=> We delivered bug-free production code
=> Complex business rules are now easy-peasy to understand
=> It even feels boring to get back to C# (we’re not over-exaggerating)
39. vpTech, the Veepee Tech Community
F#
Resources
39
■ Slack
■ F# Foundation: fsharp.slack.com
■ The Mighty Book
■ Scott Wlaschin: Domain Modeling Made Functional
■ Websites
■ F# for fun and profit
■ SlackOverflow
■ Microsoft F# Docs
■ careers.veepee.com
■ Meetups
■ Functional Programming Meta Meetup Group
■ F# Paris