DEV Community

Mohamed Dahir
Mohamed Dahir

Posted on

My adventures in ML Land

I thought it might be interesting to document my journey of learning the ML family of languages. I will try to list the resources I used in chronological order (mostly) in the hopes that it might help someone else.

Discovering and Learning F#

My first exposure to F# was through these two talks by Scott Wlaschin

I am not sure how I got interested in computation expressions but I do remember at some point thinking of ways to use it for implementing a react-hooks clone. After I started reading fsharpforfunandprofit's Computation expression series, I realized that let-expressions were a key to understanding the concept. A quick google search led to https://www2.lib.uchicago.edu/keith/ocaml-class/definitions.html

Later, I needed to write tokenizer + lexer as a part of an assignment in Nand2Tetris part two. Conveniently, this was when I stumbled on posts about using F# for writing parsers.

Things I didn't like about F#

  • Use of XML in fsproj
  • Optional and named arguments not being available to normal functions
  • Not CLI friendly as other languages. dotnet-cli is attempting to fill this gap but it is not quite there yet.
  • Cannot create a native executable that can be easily distributed.

Moving to OCaml

Because F# was originally inspired by OCaml which doesn't have any of the pet peeves I had with F#, I decided I should give OCaml a try

I wanted to write an HTTPie clone in OCaml. To do that, I started reading Real World OCaml to better familiarize myself with the language.

Real World OCaml uses Base to replace OCaml's stdlib. I am not very fond of Base since it deviates from the standard convention of passing functions before values in HOC. To fix the ordering, one has to use labels:

open Base

[1;2;3;4] |> List.map ~f:(fun x -> x * 2)
Enter fullscreen mode Exit fullscreen mode

Fortunately, there is Containers which gets the argument ordering right.

open Containers

[1;2;3;4] |> List.map (fun x -> x * 2)
Enter fullscreen mode Exit fullscreen mode

To write OCaml code, I sat up Neovim by following this guide. For my repl needs, I used Utop. Whenever I needed to insert multiple lines, I used Utop's $editor integration which could be opened by C-x C-e.

There is a lot to be desired about OCaml tooling, but I am really excited about opam-tools and duniverse.

Haskell

While searching for OCaml twitch streams, I stumbled on tsoding channel which does mostly Haskell and occasionally some OCaml.

Later, I watched some videos about Elm which counterintuitively made me fall in love with Haskell.

  • More concise syntax for lambda declaration
  • Types taking their own line
  • Infix operators with customizable associativity and precedence.
  • Can be compiled into a single binary.
  • Type classes.

One thing I missed in Haskell was F#'s pipeline operator. Fortunately, It can be easily defined.

λ> import Data.Function ((&))
λ> (|>) = (&)
λ> (<|) = ($)
λ> [1..10] |> filter even |> map (\x -> x * 2)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)