qexat's blog

For-in loops in OCaml

In my previous article, I gave a preview on implementing context managers in OCaml using binding operators.

Guess what? Let-bindings are back. This time, we will use them to emulate for-in loops in OCaml.

For-in loops

But first, let's see how for-in loops look like in other languages.

Rust

Ahh, Rust. Did you know that the original Rust compiler was written in OCaml before getting self-hosted? Pretty cool, huh?

pub fn doubled_positives(list: Vec<i32>) -> Vec<i32> {
    let mut new_items = vec![];

    for item in list {
        if item > 0 {
          new_items.push(item * 2);
        }
    }

    new_items
}

The function doubled_positives takes a list of numbers and returns its positive items twice their value. Okay, I know, this is far from being the most idiomatic Rust code, nor the most efficient. It's fine, we are just showcasing a specific syntactic feature.

ABC

ABC is a programming language of the 80s that greatly inspired the well-known Python1. Unsurprisingly, it supports the same construct as the snakey language, with almost identical notation if not for the uppercase keywords.

HOW TO RETURN doubled.positives list:
   PUT {} in new.items
   FOR item IN list:
      IF item > 0:
         INSERT (item * 2) IN new.items
   RETURN new.items

The function doubled.positives does the same as the Rust implementation. You will notice that we make use of the for-in loop both to filter out numbers and to double them.

Hey, that sounds like OCaml's List.filter_map!

That's exactly what it is here! In fact, that's the function we will use to implement our own for-in loop in OCaml.

OCaml

Now is time for our (well, at least my) favorite bactrian language!

We are aiming for something that looks like this:

let$ item = list in
  if cond item
  then Some (do_something item)
  else None

So, いきます!2

let ( let$ ) list func = List.filter_map func list

And... that's it?!

Let's see it in action:

let doubled_positives list =
  let$ item = list in
    if item > 0
    then Some (item * 2)
    else None
;;

Et voilà !

Thank you for reading through. If you like what I do, please consider supporting me on Ko-fi. Otherwise, see you on Bluesky!


  1. I know that's the language you expected to see. I like a little twist!

  2. Here we go! in Japanese. Don't misunderstand, I'm not even learning the language, I'm only addicted to that anime horse girl game. You know which one.

#ABC #OCaml #Rust #binding operators #for loops