Experiments and Adventures in 2019 with F#

0

Hi readers,

This year has been a big one in the field of software engineering for me. My close friends know that F# has always been a technology that I loved and I promised myself I would start doing more F# development than I have ever done before.

FSSF

I’ve joined the F# FSSF community and their slack. Talking to other peers who love F# as I do and it’s been a great experience thus far. The people are very welcoming and very forthcoming whenever someone has a software issue. For those who’d like to join the FSSF, here’s a link. It’ll be one of your best decisions! The community is great and very supportive 🙂

Automate grunt work & F# mentoring

At work, I had been talking a little bit about F# and it got my team excited and they asked me to present the language and why it was interesting to know more about functional programming. So for this, I created a presentation to cover

  • What is functional programming
  • What’s F# and basic features of the language
  • Differences between implementing Tic-Tac-Toe in C# and F#

Afterward, I presented a code sample I put together. I wanted to showcase a full implementation with F#. To that end, I created a sample static e-commerce app (only console) to showcase how easy it is to put in place a domain and how quickly it is to implement features from top to bottom.

Some team members have been interested in knowing more of F# and that brought in new projects at work. A coworker was telling me about creating custom UIs for clients based on requirements that could be found in an XML file. The issue he had was that with our current architecture(closely related to MVVM), it would take him about 8hrs-to-16hrs to implement only one custom UI. There was a lot of redundant work and he thought there could be some way to automate it with F#. He liked what he saw in my presentation and loved seeing how type providers worked.

After putting together a design to match his needs, I was leading in while he was implementing a solution for his problem. When we finished the implementation, we saw that it took about 80hrs for full implementation. The gain was incredible when you knew that it would have taken him 280 to 560hrs manually.

That was my first experience mentoring someone through an entire project and I can definitely see myself doing it some more. I’ve had the chance to mentor interns here and there but here we were talking of an established developer who wanted to learn functional programming and solve a problem quickly so we couldn’t spend too much time on it without proper justification.

Mentorship Program

The program is there to help out F# programmers in any given project they’d like to work on such as learning the language or start contributing to the F# compiler. On my end, I wanted to dive into full-stack development with F#. My mentor was great!

We met for 1 to 2 hrs a week for about 2 months and we were putting together a more advanced implementation of my previous e-commerce application.

The implementation covers domain-driven design, type-driven design and back-end + front-end with only F#. For those that know the React library, the great thing about F# is that you can still leverage all your know-how with only F#. The community has been pretty great at providing toolings that let developers craft great web apps with only F#.

For those who’d like to see this implementation, here’s a link to my repo. On top of this repository, you can also visit the presentation I made with the web app (ReliableElmishApps.pptx).

Performance Monitoring

At work, we had been hit by a performance regression and had no idea how this happened. Being in the DevOps team, I thought to myself, even if we fix it now, there’s no way, without proper tools, that it won’t happen again.

I started to research some performance tools for .NET and that’s when I’ve discovered BenchmarkDotNet and thought

“oh cool! That’s exactly what we need!”

Started to read on how to use and include it in our solution. Little did I know that it wouldn’t be exactly what we needed. We soon discovered with our architecture, we couldn’t use it for automated UI testing but only for low-level component and backend services profiling.

Although it didn’t cover everything in one go, it was still pretty incredible! My team had been searching for a stable solution for performance tests and the Timer ⏱ in .NET wasn’t providing stable results in different environments.

We were missing something and I explored some more to find a way to do performance profiling our implementation in an automated UI test. So I decided to go inside the source implementation of BenchmarkDotNet and see how they do it! Congrats for this by the way, really a great tool 👍🏾

I found how they could monitor the time it took for a method to complete and saw the light! I was glad to see their license was MIT so I could start thinking of my way to solve my work problem!

I implemented a performance watcher for both synchronous and asynchronous actions in .NET. That would allow us to keep using this solution were we to migrate to something else than WPF and still need performance monitoring.

Now that we had data, we needed  a way to understand said data when we’d launch many performance builds in our CI pipeline. So I went on and created another F# tool for this.

The tool parsed the performance logs I create from an automated UI test and create a performance report by leveraging the data. To get a quick understanding of, for instance, an improvement in performance from before and current state, a developer only has to give the resulting performance report in CSV to Excel and the data will be displayed in a table 🙂

First book (In Progress)

So, over the past few years, I’ve read a lot of tech books and an even greater number of blog posts from the tech community. Something in me shifted and I finally took the decision, after years of debating with myself.

“I’m going to write an F# book” I thought.

I really like F# as a programming language and the community around it! I’ll be doing a self-publish for the book so I’ll be sure to share it in the proper channels to make sure anyone that wants to read it can!

Data Structures & Algorithms

One of my areas of focus of 2020 is to revisit one core fundamental tooling of the software developer; data structures and algorithms. To be able to improve my way to approach problems at work and for side-projects, I want to make sure my knowledge is rock solid.

In the next few months, I’ll be taking a class at Coursera. As for now, I’ll be solving algorithms problems on websites such as HackerRank or Codewars until then.

I created a repository for this that I welcome readers to visit and contribute to if you feel it’s helpful. It may be a bit redundant with the variety of information out there concerning data structures and algorithms. That, we can agree on. The idea behind this effort is to lower the entry barrier to F# and let others see that it’s fairly quick to get into the game and F#’s expressiveness is a godsend for solving problems quickly and cleanly. You’ll be able to get more information right here.

Machine Learning & MLOps

This also is an effort to lower the entry barrier to F#. Some aspects of F# such as its rigid type system, its data access capabilities, and functional nature makes it a strong candidate to use for machine learning purposes.

Right now, the world has been taken by a storm with the likes of Python & R. .NET is trying to close the gap that we have and we’re getting close to what others can experiment in other development environments.

The idea here is to be able to use technologies such as Jupyter Notebooks or CI/CD pipelines and create machine learning experiments without having to be forced to learn another language. It’s not about making F# a swiss army knife, but if the tool is already great for this sort of thing, it’s pretty great to leverage it into the unknown without having to learn a new language on top of everything else.

So the idea is for me to get to know more about machine learning and how to put together DevOps pipeline for machine learning or MLOps (Machine Learning Operations). For this, I’ve bought a few books on machine learning

  • Prediction Machines by Agrawal, Ajay
  • The hundred-page machine learning book by Burkov, Andriy
  • Hands-on machine learning with Scikit-Learn, Keras & Tensorflow by Géron, Aurélien

As I’m going through them, I’ll provide my main takeaways from the books in the repository as well as my notes on machine learning courses I’ll be going through. To the best of my abilities, I’ll translate my notes to F# code since the courses will use Python as their main programming languages. You’ll be able to find more information on my progression here in my repo.

Bullet points formatter

0

Hey guys,

So this week I worked on a small code kata. The purpose of this project is to simply be able to format text into a bullet point like any text editor allows you to do it. To complete this challenge, I decide to use F# since it’s so great for prototyping and get fast results. The project had the following requirements:

  • Produce an outline of headings
  • Heading values are provided

Here’s an example of what should be printed in console :

  1. Software development is

A. An awesome thing to do

2.  Why do code katas ?

A. They are

i. Entertaining

ii. Challenging

So as we can, we have three different level of formatting to do on the string and heading values are provided for the formatting. Those requirements led to the following code :

code language="fsharp"]
 open System
 open System.Linq 

type Indexes = {
     Primaryint 
     Secondary int
     Third int 
 }
type BulletPointStyle =
     | NumberedStyle 
     | LetteredStyle 

type HeadingWeight = 
     | HW1 
     | HW2 
     | HW3 

type Heading = {
     Weight HeadingWeight
     Text string
 }

type Node = {
     Line Heading 
 }

type Outline = {
     Text string 
     HeadingIndexes Indexes
 }
 with 
     member x.addContent str = { x with Text = x.Text + Environment.NewLine  + str }

let updateIndexes (oOutline) (hHeading) = 
     match h.Weight with 
     | HW1 -> 
         let indexes = { o.HeadingIndexes with Primary = o.HeadingIndexes.Primary + 1Secondary = 1 ;Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW2 -> 
         let indexes = { o.HeadingIndexes with Secondary = o.HeadingIndexes.Secondary + 1Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW3 ->
         let indexes = { o.HeadingIndexes with Third = o.HeadingIndexes.Third + 1 }
         { o with HeadingIndexes = indexes }       

let determineBulletStyle (hwHeadingWeight) = 
     match hw with 
     | HW1 -> NumberedStyle
     | HW2 | HW3 -> LetteredStyle

let getLetter (indexint)=
     (("ABCDEFGHIJKLMNOPQRSTUVWXYZ".[index-1]).ToString())

let formatTextNode(nNode) (oOutline)
     let header = n.Line
     let mutable text = ""
     let style = determineBulletStyle header.Weight
     let indexer = o.HeadingIndexes
     match style with 
     | NumberedStyle -> 
         text <(indexer.Primary.ToString()) + "" + header.Text
     | LetteredStyle -> 
         let head = 
             match header.Weight with 
             | HW2 -> String.Join(""Enumerable.Repeat(" ",4)) + getLetter indexer.Secondary
             | HW3 -> String.Join(""Enumerable.Repeat(" "8)) + String.Join(""Enumerable.Repeat("i"indexer.Third))
             | _ -> ""
          text <head + "" + header.Text 
     text

// Folds an Outline and a list Nodes to an Outline
 let formatTextOutline(nodeListNode list) =
     ( { Text = ""HeadingIndexes = { Primary = 1Secondary = 1Third = 1 } }nodeList) 
     ||> Seq.fold (fun outline node -> 
         let text = formatTextNode node outline
         let outline = outline.addContent text
         updateIndexes outline node.Line
     )

[<EntryPoint>]
 let main argv = 
     let nList = 
         [
              { Line = { Weight = HW1Text = "Software development is" } } 
              { Line ={ Weight = HW2Text = "Super fun" } } 
              { Line ={ Weight = HW3Text = "But challenging" } } 
              { Line ={ Weight = HW3Text = "And rewarding" } }
         ]
     let outline = formatTextOutline nList
     printf "%s" outline.Text
     0 // return an integer exit code

[/code]

So basically, the process is made thanks to formatTextOutline and formatTextNode. Through those functions, I can create the Outline record that holds the formatted text and the indices for the level of formatting (Indexes). When I get in formatTextNode, I can first establish the heading style of the line thanks BulletPointStyle discriminated union(DU) type. Using the style enables me to know if I only have to take care of numbers or the letters. When I have to deal with characters, the HeadingWeight DU becomes handy to see whether or not I’ll be using a single tab (4 spaces) or a 2 tabs (8 spaces).

There you go ! 🙂

Kevin out