dennis lustre

Dennis is a software engineer crafting intuitive and tasteful experiences users want to use.

Currently first engineer @Fuerte. Previously @Boundary Remote Sensing and @Thaddeus. Studied CS @UC Irvine.

last updated 07-30-2026
← back to writing

JavaScript to OCaml: My Inevitable Indoctrination to Functional Programming

August 11, 20255 min readJavascript, gleam, functional programming, ocaml, programming

"Why is this so weird?"

This was a common phrase that I had the pleasure of repeating when I started learning JavaScript. Having had a background in imperative programming with Java, Python, and C++, it was things like Array.map, Array.reduce, that made my eyes cross -- I would naively think to myself: "yeah, I can see why people don't really like this language."

But the joke is on me. Not only were these things not the parts of JavaScript that people complained about1, but they're actually a part of a programming paradigm that I've slowly (and almost begrudgingly) grown to adore: functional programming (FP).

One of the first things in programming that truly eluded me was recursion. At the time of writing this, it's trivial to reason about a recursive function -- but I could not for the life of me understand what a function was going to return if it recurses into itself. Because all I've known is what imperative programming taught me: programs are a bunch of steps that go from top to bottom. At that point, imperative programming was so second-nature to me that I pretty much had an imaginary step-by-step debugger (thanks to zyBooks and BlueJ) running in my head, so I could always figure out what a function is going to spit out at the end. But my debugger refused to step into a function that simply calls itself.

  • talk about prof Klefstad's class which kick-started my enthusiasm for exploring programming languages that feel mysterious and new. fast forward to klefstads class. This class was called concepts of programming languages, and our projects consisted of writing code in Java, C++, Lisp, and Prolog.

This was undoubtedly the class I enjoyed the most in my undergrad. And as I'm continuing to embark on the programming language journey, I realize it may have also been a rite of passage for everything afterward to happen. Let me illustrate why: CS 141 felt like knowing how to swim and getting dropped into a pool -- and each time I miraculously doggie paddle out, I'm dropped into a deeper, more cavernous pool. But by the end of the course, I ended up becoming somewhat of a daredevil, wanting to back-flip off a diving board peering over the mariana trench.

Mario drowning in Dire Dire Docks

So where was I going with this? Well, I'd like to think that Lisp was a turning point for me in reshaping my brain. I had to learn how to read prefix notation, and I had to learn how to write functions without the ol' reliable looping constructs. This was challenging for me. I couldn't see myself writing Lisp, because it feels like the other end of the spectrum between functional programming and imperative programming.

The last project assigned in CS 141 was the extra credit project, which was what I was looking forward to when I joined this class. The premise of this project is to rewrite a concurrent Java program in a language of my choosing.

This is where Gleam comes in, a language I randomly learned about in a Theo t3 video. In short, Gleam is a language that combines the static type inference (HM types?) of OCaml and the compactness and simplicity of Go, combined with a familiar-looking, C-style syntax. This language was the perfect middle-ground for me. It walks the fine line between feeling a little bit imperative and feeling a little bit FP. It didn't take long for me to enjoy writing it, but it didn't take long for me to suffer as I tried to write a concurrent program without knowing anything about Erlang's concurrency model. Gleam doesn't have any official documentation for using actors and the like. I was in walking in the dark for a while.

Gleam Logo

But I can't help now but be thankful for the pain inflicted onto me by Erlang concurrency and minimal Gleam docs. This experience taught me how to learn when there aren't any hands to hold. And as a result, Gleam springboarded me to go out into the wild with the confidence that I can persevere and learn a new language, even when things can go sideways.

The recent uptick in Gleam popularity that incidentally occurred at the time of me taking Klefstad's course kind of feels like the stars aligning honestly.

  • talk about how programming with react and node eventually progressed to making things more concise. i had begun to discover new ways of expressing things in a more concise manner: i would occasionally stumble upon someone else's code or VSCode would nudge me with a hint. As a result, I became trigger-happy, painting over all my old code with the "more beautiful" way of doing things, and this might have also been to the detriment of the codebases that i worked with. If a function merely SMELLED like it could be expressed as a single expression with variables inlined, objects destructured, and fields shorthanded, I couldn't help myself but do it. I didn't care. I enjoyed the feeling of deleting code. I enjoyed when a function could look something like:
const doSomething = (x, y) => doAnotherThing({ x, y});

Ever so often when this happens, I couldn't help myself but sit and stare at it like a work of art that I've just perfectly crafted. "Man, that's beautiful."

And to an extent, I can still agree with my old self there: I basically still write code like this but in a different context.

  • fast forward to ocaml. With OCaml's syntax, function definitions can often feel just as terse as JavaScript's arrow functions. In retrospect, and in the context of my progression, ocaml (and i suppose FP as a whole) is, without certainty, a culmination of familiar things that confused me, delighted me, or challenged my way of thinking. And now looking back, it's pretty clear to see that I was eventually going to enjoy fp languages so much.

Footnotes

  1. The general consensus on what makes JavaScript a "bad" language is how it handles things like type coercions and equality comparisons (== vs. ===), resulting in a higher likelihood of bugs (especially for the uninitiated).