What Do Exotic Programming Languages and Single-origin Coffee Beans Have in Common?

This blog post started when I wanted to combine two of the things I love: playing around with different programming languages and brewing my own coffee with different beans from all around the world. Then, that got me thinking: how do some of the most interesting programming languages I've used relate to some of the most delicious and peculiar beans I've had the chance to taste?

Mind you, I don't consider myself to be an expert on either of the two. I can, however, share enough knowledge today so that you can learn something new! And, who knows, maybe you’ll be inspired enough to try out a new language or coffee variety.

Without further ado, make yourself a coffee, take a seat and enjoy my coffee/programming language pairings!

Ada and Venezuelan coffee: Utterly great - almost perfect - and incredibly difficult to find

I'll start things by coming clean: Ada is my favourite programming language. And I'm originally from Venezuela. So there's going to be some bias here. However, I'm pretty sure anyone who’s tried Ada can admit that it's a hell of a language! And Venezuela has always been pretty well known for its amazing coffee and cocoa beans, so hopefully, I'm not too detached from the truth anyway.

What makes them so great, then? When it comes to Ada, one has to first understand what it was made for: highly secure and reliable systems. Which explains many of the things surrounding the language; a very strict type system that's also incredibly expressive, it possesses a weird array and string types that force you to always define their size so that the compiler can guarantee that there's not going to be an overflow. Plus, its syntax, while seemingly verbose at first, is very well suited for readability (something that makes a lot of sense, given that we spend way more time reading software than writing it).

All in all, Ada is a very well-thought-out programming language that makes way too much sense most of the time and thus, in my opinion, lends itself quite well for learning programming concepts, since it's a language that aids you a lot in your thinking process.

Unfortunately, though, it's garnered a bad rap since the very beginning for its relation with the US Department of Defence and being a closed language with a paid compiler. Nowadays, you can download a free version of it, but it’s still not widely used. Many issues you'll find while developing will not be as simple to solve as doing a Google search or looking on Stack Overflow.

As for Venezuelan coffee: if you can imagine how good coffee should taste like, then you pretty much know why it's so highly regarded. Because of the country’s currently “fragile” state, it's not as readily available in your everyday roaster coffee shop. Same as with Ada, if you get your hands on it, please try it. You won't regret it!

with Ada.Text_IO; use Ada.Text_IO;

procedure Drinking_Venezuelan_Coffee is
    type Level_Type is range 0 .. 100;
    type Coffee_Origin_Type is (Venezuela, Kenya, Rwanda, Sumatra);
    type Coffee_Mug is record
        Level : Level_Type;
        Coffee_Origin : Coffee_Origin_Type;
    end record;
    procedure Fill_Mug (M : in out Coffee_Mug) is
        case M.Level is
            when 0 .. 99 => 
                M.Level := Level_Type'Last;
                Put_line ("Mug filled!");
            when others => 
                Put_Line ("Mug is already full!");
        end case;
    end Fill_Mug;
    My_Mug : Coffee_Mug := (Level => 0, Coffee_Origin => Venezuela);
    Fill_Mug (My_Mug);
end Drinking_Venezuelan_Coffee;

Pony and Kenyan coffee: Down-to-earth and inconspicuous, but full of flavour

What I like a lot about Kenyan coffee is that it's a very grounded coffee. You can almost taste the earth with every sip of it. If you don't get what I mean, imagine the amazing smell of earth just before it rains. Yep, Kenyan coffee tastes that good!

That same feeling is the one I get whenever I do something with the Pony language. Pony is a very welcoming programming language because it doesn't try to be more than it is. And yet, what it has to offer is quite powerful and unique. For starters, Pony is an actor based language. If you are familiar with Erlang or using channels, you'll get the gist of it. But if not, think of every actor as a living object (or process) that communicates with other actors by sending and receiving messages. This already makes Pony quite suitable for concurrent systems and programs, but there's more: Pony is also a capabilities based programming language, in which everything has a set of rules that tells you what you can and cannot do with it. For instance, a variable with the Value capability is read-only, which means that you can safely share it between your actors. A variable with the Reference capability is mutable, which means that you can't pass it around. There are of course many more of them, but hopefully you got the gist of it. All of this comes packaged in a nice syntax that reminds me of Python, which is always a nice language to read.

Did it sound compelling? I hope it did! And if you decide to try Pony, please ask a friendly barista to make you a cup of Kenyan coffee to go along with it. You can have it however you like, but I recommend it black and without sugar.

actor Customer
  let name: String
  var _coffee: String = ""
  new create(name': String) =>
    name = name'

  be ask_for_coffee(b: Barista) =>
    b.prepare_coffee(this, name)
  be receive_coffee (coffee': String) =>
    _coffee = coffee'

actor Barista
  let available_coffee: String
  let _out: OutStream
  new create(available_coffee': String, out: OutStream) =>
    available_coffee = available_coffee'
    _out = out

  be prepare_coffee(c: Customer, name: String) =>
      _out.print("One " + available_coffee + " coffee for " + name)
actor Main
  new create(env: Env) =>

  var barista = Barista("Kenyan", env.out)
  var customer = Customer("Jane")

Reason and Rwandan coffee: Familiar on the outside, amazingly exciting on the inside

If there's something that Reason and Rwandan coffee have in common, is that they both look like something else at first glance. When it comes to Rwandan coffee it just looks like, well, any other coffee, but when you try it… uff, it's like no coffee you've ever had!

As for Reason, from a syntax point of view, it's eerily similar to JavaScript. This happens for a good reason (pun intended): it's a language mostly directed at JavaScript developers. Reducing "grammar friction" is one of its objectives. However, under that first superficial layer of familiarity lies a different language in many, many ways.

First off, Reason, unlike JavaScript, is powered by OCaml. You could say that it's a syntax layer on top of OCaml. At its core, it has the kind of strong and rich type system that JavaScript could only dream of (I still love you, JavaScript, just not in the same way!). With Reason, you'll be able to construct better software that's easier to rely on. In addition to that, you can compile to both JavaScript and OCaml, giving you access to two very mature ecosystems at once. Oh, and if you needed one more reason (yes, pun intended… again) to try it, two words: pattern matching. Think of it as a sort of switch statement that lets you match the shape of your data instead of just doing it by an explicit value. Trust me, once you use a language with pattern matching, you'll miss it whenever you're using one that doesn't!

If you feel like trying out something new but don't feel like going too far from your comfort zone, be it other kinds of coffee or programming languages with C style syntax, then maybe you should consider checking out Reason or Rwandan coffee, you can't go wrong with either one!

let workingHours = 8;
let workStartsAt = 9;
let myPreferredDrink = "Rwandan coffee";

let translateTime = (hour) => 
  hour < 13 
  ? string_of_int(hour) ++ "AM" 
  : string_of_int(hour - 12) ++ "PM";

let whatToDo = (firstHour, currentHour, drink) => {
  let timeOfDay = firstHour + currentHour;
  let atTime = (predicate) => 
      "At " ++ translateTime(timeOfDay) ++ predicate ++ "!";

  switch (timeOfDay, timeOfDay mod 2) {
  | (_, 0) => atTime(" drink more " ++ drink) 
  | (13, _) => atTime(": Lunch break")
  | _ => atTime(" drink " ++ drink)

for (hour in 0 to workingHours) {
  Js.log(whatToDo(workStartsAt, hour, myPreferredDrink))

Idris and Sumatran coffee: Strange, hard to grasp and filled with incredible depth

When it comes to programming languages that I enjoy playing around with, a certain group of so-called functional programming languages is at the top. One of the most popular in that group is Haskell, from which Idris takes a lot of cues.

One of the core tenants of a functional programming language is that functions are first class citizens. You can treat them as you would any other value, which allows for pretty powerful things like returning functions or passing them around as arguments to other functions. They also tend to feature very strong type systems. However, one other thing that makes languages such as Idris so special is their declarative syntax style, which looks more as if you were describing things instead of the more intuitive command-like style (do this, then that) of writing imperative style code.

Sumatran coffee is also a very special kind of coffee because of the way in which it's processed, as well as the kind of climate where it grows. This makes it so that Sumatran coffee tastes quite different from what you would expect coffee to taste like. It tastes almost foreign to someone more used to the kind of "regular" coffee you would find at your average café. In the same way, Idris or Haskell look almost foreign to someone used to more imperative programming languages like C or Java.

Yet, besides all that, Idris most distinctive feature is not that it's a functional programming language per se, but rather something more unique: dependent types. You can enhance a type by providing a value together with it. A good example for this would be the concat function, which would be typed something like List n t -> List m t -> List (n + m) t. The first argument will be a list of n elements, the second a list of m elements and the result will be a list with n + m elements. How cool is that?! With dependent types, you gain a whole new level of control over what to expect from your code. In my book, that’s always good.

Whenever you're ready to try something different and exciting, be it Idris, Sumatran coffee or (even better) both: be prepared and enjoy the ride!

isSumatranCoffee : String -> Bool
isSumatranCoffee "Sumatran" = True
isSumatranCoffee _ = False

drinkOrPass : String -> String
drinkOrPass coffee = case isSumatranCoffee coffee of
  True => "I'll have some of that Sumatran coffee, please!"
  False => "No thanks, I’d rather have something else"

main : IO ()
main = putStrLn (drinkOrPass "Sumatran")

There are of course many other programming languages and coffee beans that are worth talking about. Like Nicaraguan coffee with its acidic notes, the aromatic wonder that Ethiopian coffee is, the esoteric 8th with its stack-based syntax or Clojure (which is a cool language (based on Lisp (which means (it uses lots of parentheses)))).

Hopefully, I got to pique your curiosity on at least one of the combos that I paired above. Few things are as fun as trying new programming languages. Combine that with a cup of coffee made with freshly roasted beans, and you're all set!