My adventures in ML Land
Mohamed Dahir
Posted on March 20, 2022
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
- OCaml basics and structure of ocaml programs
- A Crash Course in OCaml Modules
- OCaml alternative syntax for F# computation expressions
- Opam docs
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)
Fortunately, there is Containers which gets the argument ordering right.
open Containers
[1;2;3;4] |> List.map (fun x -> x * 2)
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)
Posted on March 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024
November 29, 2024