Magic isn’t real
Any sufficiently advanced technology is indistinguishable from magic.
I’m somewhat of a language nerd to begin with, and it was Rust that originally got me interested in the whole functional paradigm.
Not due to it’s lineage, but the heavy use of chained iterator methods in favor over traditional loops. This is one of the more intimidating hurdles
for newcomers to the language, but after getting used to it, rarely will you see anyone write a for
loop again.
Rant: The argument can be made that what I’m talking about is more similar to Javascript-land where a bunch of pseudo-functional methods and terminology are
used, but it in reality is as far away from functional programming as useState()
would imply it is.
At least Rust has a few things to back it up, as at least a language that will support you should you desire to write pure functional code. I would argue that for beginners, Rust will simply force you to write functional, immutable code, whether they really understand it or otherwise, as the amount of .clone()
‘ing required for a newcomer to compile a non-trivial program will practically almost guarantee that nothing was actually &mut
ated*.
So this got me interested in watching some GOTO, strangeloop, and other conference talks about functional programming. Upon discovering @artemslab (definitely go check it out, absolutely fantastic high quality, very in-depth content) on YouTube and watching some videos, and reading about and it’s runtime integer representations and memory allocation, that really got me fascinated with the language. One of the programs that he demonstrates is a huge static analysis tool written in Ocaml, called ‘Infer’, that I had never heard of, but seeing the scale of this project and the adoption by some huge companies I was super impressed and even more excited to maybe build my next side project in Ocaml, if for nothing but the learning experience. (and possibly a little street cred in the Rust community, if I’m being honest ;)
In the past I typically wouldn’t hesitate to just sudo pacman -Sy
whatever compiler or interpreter I needed, to get started playing around with whatever new language I was interested in. However since getting full-time employment, on top of the existing OSS stuff, as well as doing some contracted gigs for the facility I’m in, I haven’t had so much as a moment to spend on anything fun quite some time.
Anyways, as usual I’m off track here. My point is that I thought I had a good introduction to the world of FP, and I thought since I’d heard that many of the features and some of the syntax we love from Rust came directly from tha ‘Caml itself, I thought I would love it immediately and thought perhaps picking it up would be at least as simple as picking up any other language and I could count on the same method I rely on.
Well, I think anyone who has tried to jump from C based languages to the ‘ml’ or FP world, can probably tell you how foolish of a thought that was.
My plan was to do the entire Advent of Code in Ocaml, then I was going to pick an ambitious project that I would otherwise use Rust for, and simply force myself to use Ocaml. I find this is the best way to learn a language, is just take on a project that is significantly more ambitious than your current skill level, and by the time you finish it, you’ll have not only saved yourself a bunch of wasted time on tutorials that aren’t actually teaching you anything but how to copy from someones screen in a youtube video, but you’ll have made something cool :D (hopefully).
I underestimated how much I would be thrown off by the fact that the types are heavily inferred, and are almost never explicitly declared, from what I can tell. I found that the combination of this and the strange syntax really screws me up, as now I am having problems inferring my own types at this point…
When dealing with lots of recursive functions, you find yourself looking up often at the function signature to view the parameters, but the concise syntax makes it difficult to mentally parse quickly.
Example, random code snippet from ocaml.org:
let group list sizes =
let initial = List.map (fun size -> size, []) sizes in
let prepend p list =
let emit l acc = l :: acc in
let rec aux emit acc = function
| [] -> emit [] acc
| (n, l) as h :: t ->
let acc = if n > 0 then emit ((n - 1, p :: l) :: t) acc
else acc in
aux (fun l acc -> emit (h :: l) acc) acc t
in
aux emit [] list
in
let rec aux = function
| [] -> [initial]
| h :: t -> List.concat_map (prepend h) (aux t)
in
let all = aux list in
let complete = List.filter (List.for_all (fun (x, _) -> x = 0)) all in
List.map (List.map snd) complete;;
val group : 'a list -> int list -> 'a list list list = <fun>
;;
Even when you learn what it actually going on here, and it makes immediate sense to you.. It must take a while before it becomes easier to read.
Two things every Computer science student learns, and then are immediately told to never use again*…
Anything that can be done recursively can be done iteratively (and most optimizing compilers will replace your recursion anyway), and linked lists are slow and inefficient with modern CPU caches, and you should almost never use them (and if you’re a web dev, well, you just wouldn’t anyway).
You could describe Ocaml as a language that relies heavily on both of these things. This feels even more strange that it might seem it would, and I have found myself stumbling on absolutely remedial tasks.
Yes, there are libraries with other data structures, and there are in fact for
loops (and even while
loops), However I feel like I will end up learning more of the language and find that iterator methods will be used more so than any of these, much as in Rust.
Thought provoking. If you don’t believe there is anything to gain from being forced to think about something you do every day in a completely different way… well I’m surprised you made it this far into the post.
Awesome mixture of !significant-whitespace and !brackets. And how cool is the comment syntax? (* doesn’t it just feel like.. middle-eastern-ish *);;
Tooling: is way better than it has any right to be, considering the size of it’s user-base and community.
Great conversation starter, really cool and helpful community.
Lots more to learn for sure but these were my initial thoughts anyway, I do really want to like it so we will see how much that helps. I just definitely did not get the head-start I was expecting, but I don’t think that’s a negative thing it just means there is more to learn.
*obviously I know this isn’t true and an extreme exaggeration, but I thought it was funny. There’s always someone who will ‘well ackshually’ you when you think you’ve been completely clear.
Also, once again have to plug @artemslab. Doesn’t have NEARLY enough youtube subscribers for how good the content is.
Any sufficiently advanced technology is indistinguishable from magic.
My story, and how this is all possible
(Modern) PHP: Does it really suck?
Processes, Pipes, I/O, Files and Threads/Async
Unsolicited advice for anyone seeking to learn computer science or software development in 2023.
How I got here is already far too long, so I must include a separate post for all the credits and gratitude I need to extend to those who made this possible.
Following up on the first impressions post, let’s solve a problem in OCaml and compare the Rust solution.
Humorous article, completely unrelated to, and written before, the others ended up actually on the front page.
OCaml: First impressions