DEV Community

Mohamed Dahir
Mohamed Dahir

Posted on

4 2

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay