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)
Top comments (0)