I absolutely love Scott Wlaschin’s work. He breaks down the unfamiliar and sometimes complex ideas of functional languages into approachable explanations. My one gripe with his site is that there is a bit of an implicit order to the content. Here’s my outline of how I think the concepts best build on each other.

I know he divides posts into topics in his site contents page, but it isn’t really a reading order. Some of the early series recommend pre-requisites, but not until you already start reading.

This guided reader starts at “Why would I learn another language” and aims to leave the reader at “I can picture a wholistic functional system”. Nothing can replace experimentation and application for developing a working understanding. However, this list should provide a fairly gentle curve for introducing the concepts.

If you’d rather just dive in, then his videos are a great place to start. His videos embody the most critical ideas on his site, and almost every video also points to an equivalent blog series.

Full Path

  • Four Languages from Forty Years Ago
    • Great motivation on why learning languages is important and the most important language types to learn
    • Also desirable language properties
  • Learning F#
    • Good advice on the mindset for learning F# or any functional language
    • Also leads into the starter series
  • Functional Design Patterns
    • Introduces functional concepts in an approachable way that leans on knowledge from OO patterns. Helped me feel like I wasn’t throwing away all the practices I built up
  • Why F#
    • At least read up to the Comparing F# with C# posts to get a gentle introduction to F# syntax
    • Most of the rest of this series previews ideas that later series will cover. Most of the posts are very quick reads and do not need to be read in order.
  • Thinking functionally
    • Dig into the concepts of functional programming
    • Set the right mindset for getting the most of FP and not just a poor mapping of OO into a language not suited for it
  • Understanding F# Types
    • A quick read that clarifies F# types not typically found in C# or other OO languages
    • It suggests first reading Expressions and Syntax, but I think this series can be read later.
      • Expressions and Syntax is a deeper dive into syntax and the motivation for F# syntax decisions. I’d almost recommend coming back to this one later to avoid even knowing the imperative syntax, though he does preface every imperative expression with a way to avoid it
  • Railway-Oriented Programming
    • A powerful metaphor for functional composition
    • Introduces the mental schema for how parts build up into flows in a functional way. Also clarifies the benefits of composing this way
    • The Functional Toolkit is good if you want more on composition
  • Domain Modeling made functional or blog equivalent Designing with types
    • Introduces how to encode your domain with types
    • Types in F# are lightweight so we can enforce more of our domain without a burdensome amount of boilerplate
  • A Recipe for a Fully Functional App series
    • Starts to pull together the techniques into the bigger picture of a system
  • Functional Approaches to Dependency Injection
    • DI is a big part of how I comprehend systems in the C# world. This article helped me come to terms with how the same concerns are preserved in a functional world, a big step toward making larger systems.
  • Designing with Capabilities
    • Takes type-driven design a step further to limit potential security and design abuse
  • Enterprise Tic-Tac-Toe
    • Pulls most of the ideas together into a worked example. A nice example of the thought process and some practical bits like information hiding techniques
    • Calculator Walkthrough is a similar example
  • Code Review/Refactor
    • Review of the major concepts with very helpful highlight of smells and refactorings
    • You’ll want to have tried making a small system by now
  • Property-based Testing
    • A different approach to testing. Not strictly functional, but plays well with Type-Driven systems.
    • A good complementary approach to Unit Tests. Seems to effectively test some of the hardest qualities to pin down with example-based testing
  • Elevated worlds
    • Demystify monads and similar types that make composition so powerful in functional programming
    • Getting into the workings of techniques for matching up types in composition, as well as some inversion of control (state and reader monads)
    • Dr. Frankenfunctor and the Monadster is another good example to follow up with
  • Monoids Without Tears
    • Understand another underlying concept for effective data structuring

Advanced Topics

  • Recursive Types and Folds
    • A deeper look at how to build recursive types and hide the recursion behind one method
    • Very useful. I ran into this issue sooner than I thought. Recursion happens in domain models more than expected
  • Computation Expressions
    • A deeper dive into implementing computation expressions (the language mechanism for simplifying monads)
  • Type Size and Design
    • A useful look at the equivalence/mappability of different types or design choices
  • Dependency Cycles
    • Not really advanced. If you’re having a hard time buying into file ordering in F#, this explains why it the language does it and why it is useful.
  • Swapping type-safety for high performance using compiler directives
    • A experiment for low-disruption optimization of type-driven designs. A good read if you’re worried about theoretical performance, but shouldn’t be used unless proven it’s needed

Tools for Experimenting

I highly recommend you try out these ideas as you work through the readings. It is a lot to digest and the best way to process it is by doing. Scott Wlaschin has a similar post, but a lot has changed since then.

Here are tools and tips for working in F#

  • The common errors you’ll see are very different from C#-like languages. It can be really frustrating at first. Check out Troubleshooting F# for some tips.
  • Type fiddling: Use the F# interactive
    • Works much better for fiddling than the C# interactive because F# definitions are more compact. Everything in F# is also an expression with proper REPL output
    • Run dotnet fsi from your favorite terminal. It should be pre-installed with and .NET SDK
  • Script Fiddling: VsCode Interactive Notebooks
    • It is still in preview and has some quirks, but is still plenty good for playing around.
    • Compatible with Jupyter files, but has better code completion and syntax highlighting than F# (or C#) in Jupyter labs.
  • Editor (app-level experiments): VsCode with Ionide plugin
    • Ionide comes with syntax highlighting, goto definition, type hints, project view, and more
      • beware that you many need to rebuild to get some errors to go away
    • I think the most invaluable part is the type signature lenses. Implicit typing causes some of the hardest errors to adjust to upfront. Seeing the type signatures inline makes those errors much easier to spot
    • Visual Studio is fine if jumping IDEs is too much to start with
  • Unit tests: xUnit or Expecto
    • I like to explore via unit tests. I find them more durable and visual than a REPL, especially once I’ve gotten into sample apps
    • xUnit has better IDE support and should be more familiar for C# users than Expecto
    • If you’re new to VSCode and don’t have a test runner, try .NET Core Test explorer
      • WARNING: you need to set a search path for tests (e.g. **/*Tests.dll) or it’ll take forever to discover tests

Minimal Concept Sampler