Simple Things with F#
Tags: rest, server, fsharp, sorting
Published: 2020-01-03 01:46:23


## What things?

So, I'm very passionate about **learning new programming languages** and discovering why people like such languages. Is it a perfomance aspect? Robustness? The code looks pretty?

I tend to always go for the language website itself looking for information of "how to start" and, most of the time, I find a pretty solid documentation, with nice references to frameworks, online courses and all... But, usually, I have to read different resources for building a "simple complete" thing (like a server or so), so I decided to build a series of posts telling **how to build the basics with language X?**

For the basics, I chose:

- Implementing the [QuickSort](https://en.wikipedia.org/wiki/Quicksort) algorithm
- Reading a file from the _filesystem_
- Building a HTTP server that parses JSON

Depending on the language and its environment, I may talk about installation and setup.

## Let's go with F&#35;

So, F# _(pronounced F-sharp, and also how you might get better results on Google)_ is a programming language from *Microsoft*, part of the .NET framework, and it supports multiple paradigms, although it's way more used as a **functional language**, coming with a strong type system. F# is part of the [ML family](https://en.wikipedia.org/wiki/ML_(programming_language)), being inspired by the language OCaml. It has a great community, multiple tools to using it in different scenarios (like [turning into Javascript](https://fable.io/)), and the F# code usually looks **really concise**, specially when building complex systems with lots of entities. 

>There's a great website with resources about F# that every developer should read: [F# For Fun And Profit](https://fsharpforfunandprofit.com/)

For start using F#, you can [read the guide](https://docs.microsoft.com/en-us/dotnet/fsharp/get-started/) from Microsoft, where it tells you how to install it on different platforms and integrate it on your preferred code editor. On my setup I use the `dotnet` CLI from the .NET SDK.

After all setup, run `dotnet new console -lang F# -o simple-things`. It will scaffold a simple **console application**. You can test it entering the `simple-things` generated directory and running `dotnet run` or `dotnet watch run` for re-running on every change. Opening `Program.fs` will show the code for the application.

### 1. QuickSort

For the [sorting code](https://stackoverflow.com/posts/1982056/revisions), I chose this from StackOverFlow. It uses a bunch of nice features from the language. You can paste it right over the `main` func:

```fsharp
let rec qsort: int list -> int list = function
    | [] -> []
    | x::xs -> let smaller = [for a in xs do if a<=x then yield a]
               let larger =  [for b in xs do if b>x then yield b]
               qsort smaller @ [x] @ qsort larger
```

The `let` form declares the function `qsort` that **supports recursion**, which is not [the default](https://stackoverflow.com/questions/900585/why-are-functions-in-ocaml-f-not-recursive-by-default), indicated by the keyword `rec`. The `int list -> int list` is the type annotation: this function receives a list of _int_ and returns one also.

The `|` stuff going on there is called **pattern matching**, and it's a very useful tool with [much more uses](https://fsharpforfunandprofit.com/posts/match-expression/). This kind of function declaration omits its parameter declaration, and will try to match it right away. If it's a empty collection, it returns `[]`. If not, it will perform the _pivoting_ of the algorithm.

The `for .. in ..` form it's a handy tool for dealing with collections, and you can read more about it [here](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/loops-for-in-expression). One could also use `List.filter` or `List.partition` for creating the new lists.

And, finally, the `@` operator is used for concatenating lists. 

Calling a function in F# is as simples as writing the name of the function, a space, and the input. No parenthesis necessary. You can test it!

### 2. Reading a file from the _filesystem_

This is the part where we use F#'s .NET API, what's really cool. There's also a inter-op with C# code, so that makes finding packages really easy. For reading a file we'll use the `System.IO.File.ReadAllText` function, which takes a file path and returns its text content. Just add `open System.IO` to the beginning of the file and let's try:

```fsharp
    let readFile(path: string) = File.ReadAllText path
```

And that's just it. You can test it calling `readFile "1.txt"` for example. I explicitly added the parameter `path` here for showing how we can do it.

### 3. Building a HTTP server that parses JSON

This is, with certainty, one of the most popular topics regarding any programming language. Using F#, you can setup a HTTP server without a hassle, and there are a lot of other [options](https://fsharp.org/guides/web/) if you wanna do things differently.

When doing functional programming, the **simplest approaches** are usually favored. Instead of using a complex framework with all the boilerplate needed, you can get some libraries, **hook them together**, and get the same end result. Of course, this comes with the cost of more decision making, what can be harder for beginners, but the community are usually quite helping about starter guides. For this post, I've chosen to use [**Suave**](https://suave.io/).

#### Parsing

**JSON** is a popular format for sending and receiving data over the WEB, used by a number of WEB APIs. It's simple, human-readable, and lighter than other formats. Since it's not a core feature of F#, we will need to import a library from somewhere. There a lot of great JSON parsers out there on the .NET environment, like [Newtonsoft](https://www.newtonsoft.com/json) or [Chiron](https://github.com/xyncro/chiron), but Suave **already comes with one.**

There are two ways you can do this: **providing the input type**, or reading the JSON from **whatever format it came**. We are using the former and you should too, since a lot of F# benefits comes from **well defined types**. There's a lot more about typing like the awesome type inference the language has, or the [Type Providers](https://docs.microsoft.com/pt-br/dotnet/fsharp/tutorials/type-providers/), but it's another post's matter.

```fsharp
[<DataContract>]
type Input =
   { 
      [<field: DataMember(Name = "list")>]
      list: int seq;
   }
 
[<DataContract>]
type Output =
   { 
      [<field: DataMember(Name = "result")>]
      result: int seq;
   }

```

This sets up our input and output data types, and we will use them when creating our server. We need to explicitly set the JSON keys for the keys of our types.

#### Creating the HTTP server

[**Suave**](https://suave.io/) is a a lightweight, non-blocking web server for F#, and it's super simple to setup a server. After installing it with `dotnet add package Suave` (or using NuGet directly), you can just insert on your `Program.fs`:


```fsharp
open Suave

startWebServer defaultConfig (Successful.OK "Hello World!")
```

Wait for the watcher to restart your program, and you have a **http://localhost:8080** on the air. With a bit more of configuration, you can setup a routing supporting other path or methods.

So, let's configure a **POST route that uses our QuickSort** and reads/returns JSON data.

```fsharp
// You need to open some packages to use this functions, check the final code below

let sortHandler: Input -> Output =
    fun input -> { result= qsort (Seq.toList input.list) }

let app = 
  choose
    [ POST >=> choose
        [path "/" >=> Json.mapJson sortHandler]]

[<EntryPoint>]
let main argv =
    startWebServer defaultConfig app
    0
```

This is it. Let's test:

![Testing our server on Postman](https://i.imgur.com/6viK055.png)

**Final Code**: [https://github.com/luciannojunior/simple-things-fsharp](https://github.com/luciannojunior/simple-things-fsharp)

### Some things to point out:

1. The `Json.mapJson` comes from `Suave` and it basically transforms a "normal" F# function into a HTTP handler that transforms the request body into F# data (the function parameter), and also the function response into JSON ready to the response. You can learn more about it [here](https://suave.io/restful.html)

2. I've run into problems using F#'s _list_ for the JSON types, so I had to use `seq` (that is [more advisable](https://stackoverflow.com/questions/10814203/when-to-use-a-sequence-in-f-as-opposed-to-a-list) when integrating with .NET code), so I need `Seq.toList` to pass the data into our sort `int list -> int list` function. It wasn't necessary to transform the output due to automatic casting.

3. It was very easy to setup this simple demo, but I took some time until realizing that a very strange error was happening because **I was testing the POST route without passing a body**. It wouldn't be hard to wrap `mapToJson` into a request-safe middleware.

4. I use **vim** as an editor, and couldn't setup my ALE to work with F#, so autocompletion was not happening. I believe that using a MS editor would be a more pleasant experience.  

5. I've used `dotnet` because it was already installed on my machine, but for the next posts I'll probably use something like Docker.

I would appreciate **some feedback**, as I hope to return with the series with another language soon. See ya!