in the beginning, after the earth cooled...
I've been programming since getting a Commodore VIC-20 in the early 80s. Those early hacks were far from "functional programming". Typing out loops & gotos from code listings printed in magazines like COMPUTE!, RUN, and BYTE, I was a literal "script kiddie". In the Summer of '90 – after my first year at Texas A&M – I got my first paid gig. Hired for data entry, I pitched my employer that I could write what would be now be called a "Customer Relationship Management" system for him. The rest of the Summer was spent getting it done with Borland's Turbo Pascal. It was no Salesforce.com but it solved a problem for my first customer.
As my professional work took off I got a variety of experience. My "full stack" work typically consisted of a Windows desktop app, communicating with a device across a cable, collecting data from the device, and persisting the data locally; reporting, charting, interacting with the data; shipping that data across the internet. And for a good number of years, especially early on, writing the embedded code for the devices based on Motorola 68k & Motorola 56k DSP. Language-wise I spent the most time writing unmanaged C++. The embedded work was typically C and sometimes required some Assembly.
Overall I thought of myself as an Object Oriented programmer. OOP was the best way to design software with a high level of Quality, right?
I know that I heard a bit about functional programming during a "Programming Languages" class in college. There was an assignment with Lisp. What I got out of it: lot of parenthesis and it was kinda weird. Whatever goodness was there was lost on me.
Pretty quickly LINQ became important in how I wanted to work with data. I didn't come to it through Entity Framework like most people did. But when dealing with lists of data I fell in love with the conciseness of Where & Select functions. "Look Ma! no foreach and no ifs!"
the great awakening
The real revelation came when I was working on a side project. Kris Akins slacked me on August 2017 at 7:07pm CST:
Hey when you get a chance, let me know your thoughts on this: [code gist]. I'm starting to use this
Option<T>in my projects to avoid returning/checking for null values.
It was just one thing, an Option type for C# that he started using after watching a Pluralsight course by Zoran Horvat. So I read a few of Zoran's articles and watched a couple courses (his stuff is some of the best on Pluralsight).
Soon I ran across Paul Louth's LanguageExt library and started using it in my projects. Using LanguageExt wasn't naturally easy for me. At first I just used it a bit each day, basically saying "ok, it is FP time, let me sit and think this one through" and working through a small problem.
Learning to program with "functional" concepts is hard. The traditional imperative approach seems intuitive, but that is likely only because it is what we've been doing since the beginning of our programming lives.
- me, posted 29 September 2017
Soon after starting to use this I was showing it to others at work. We had a "lunch-n-learn" to talk about FP concepts and presented examples using LanguageExt. Then we elected to use the library in a greenfield Android project. The benefits were apparent and the team enjoyed trying to solve problems in a new manner.
The key thing with functional programming in C# is being strict with yourself, as it's easy to fall into the OO habits. - @louthy
The need "to be strict with yourself" when doing functional programming in C# is important. C# is a great language and I love it. But it lets you do all kinds of things without pushing through turnstiles. Something like "change the value of a variable" sounds innocent. Even the term variable describes what we want to do with it. But when you vary the value of the variable you may be vexed.
Time after time during debugging, since retraining my thinking, when the problem is identified the realization is "if we followed FP principles this would not happen". That is not to say that the problem was due to OOP. Rather, it is easier to follow FP principles than all the patterns required in order to do good OOP.
How can we fall into a "pit of success"? (Mark Seemann uses this term; so does Isaac Abraham; there are probably others.) The answer is to use a functional programming language, or at least a "functional first" language, so that we are guided along the good path. F# is that language for the .NET ecosystem.
September 2019, two years after my first steps in FP, I took a joy ride to San Francisco to attend OpenFSharp. I wanted to spend time visiting with others who use F# day in and day out, and to attend presentations that might help things to "click". I actually went a day early and was able to spend a full day in training with Scott Wlaschin, famed for both fsharpforfunandprofit.com and Domain Modeling Made Functional.
Once back in Texas it was back to work. Luckily I was starting on some new functionality with a few other devs. I chose to implement the new required data models and logic in F#. This meant adding a new assembly into the solution with a very specific purpose. I can't say that it was absolutely pain free, but it wasn't too bad. The F# Software Foundation community helped us resolve issues quickly. (The problems were resolved by tightening up our build tooling.) Had our team had no prior exposure to FP principles some might have balked. Instead the response has been very positive. Everyone has shown interest in learning more: Not only because programmers often like new things, but because we've seen the benefits of FP.
ok! how can I get in on this?
This month there is a flurry of activity from F# enthusiasts due to the 2019 F# Advent Calendar organized by Sergey Tihon. Each day during December there are F# blog posts scheduled to arrive, of which this is one for the 12th. You can find them each listed on Sergey's page and see related tweetings with #fsharp and #FsAdvent.