Hello, world!

This is the personal website of me, Marcel Garus (he/him). Here's a bit about myself:

  • I'm a student at the Hasso Plattner Institute. Currently, I'm doing my Master's degree in IT Systems Engineering here in Potsdam.
  • I do a lot of programming, almost all open source. I have a bunch of repos on GitHub. I work mostly with Flutter or Rust. Most notably, I'm creating a new programming language called Candy.
  • Sometimes I write on this blog. Most articles are about programming stuff, especially programming languages.

If you want to get in contact, here are some options sorted in my preference order:
Telegram, WhatsApp, Email, Twitter

With that, enjoy reading!


Thoughts on Zig

2024-02-05 · 6 minute read · Zig · programming language design · Martinaise · code

For some time, I've been keeping an eye on Zig, a systems programming language. Contrary to C++ and Rust, it doesn't introduce more complexity to improve (memory) safety or expressiveness. Instead, it has a similar complexity to C, but cleans up the weirdness, choosing sane defaults for most operations.

Martinaise: A Simple, Imperative Language

2024-01-11 · 7 minute read · Martinaise · programming language design · code

You might know that I already created some programming languages (Mehl, Candy, Dungbeetle). So, why yet another language?

I've written both low-level and high-level languages, but all of them are dynamically typed. Well – our initial version of Candy was typed, but we switched to a completely new, more general feature (needs). Having such a grand vision is exciting, but it bothered me that I didn't get to implement some of the compiler techniques I researched, such as a type solver.

To scratch that itch, I created Martinaise, a new low-level, statically-typed, imperative language with function overloading. Martinaise is a recreational hobby project by me, for me. It doesn't aim to change the world. Its only goal is to be useful to solve simple problems such as from Advent of Code.

Why Candy Doesn't Have Built-In Concurrency Anymore

2023-12-05 · 3 minute read · Candy · programming language design · code

Until recently, we supported primitives for structured concurrency in our programming language Candy. You can find the details about the design and implementation in the last article, but the short version is that there were built-in functions for operations such as starting multiple parallel execution threads.

We compile Candy code into bytecode for our VM. Recently, Clemens started working on an LLVM backend as an alternative. As part of that, we started thinking more about how Candy interacts with the platform it runs on.

Concurrency In Candy

2023-12-04 · 3 minute read · Candy · programming language design · code

As of 2023-08-10, concurrency in Candy works differently. See this article for the reasoning behind that.

Many programming languages have the option to spawn a new thread. A downside of this is that the control-flow becomes non-local: If you call a function, you can't see if it starts another thread that then runs in the background.

sin(2) // may spawn a thread? who knows?

Candy is a functional language and we want functions to be a perfect unit of abstraction – you should know be able to reason about a function call without looking into the function's source code. That's why we opted to use structured concurrency.

concurrency with threads vs. structured concurrency

The Candy Compiler Pipeline

2023-09-29 · 18 minute read · Candy · Rust · code

See the previous article for an introduction to Candy, a new programming language.

An interesting property of Candy is that every time your program panics, a single call site can be made responsible. This is a necessary to enable good tooling using fuzzing – for found crashes, the faulty call site can be highlighted in the IDE.

From a compiler-building perspective, this also makes the Candy compiler quite unique. In this article, I'll show a general outline of the different compilation stages.

compiler pipeline mountain

Solving Kakuros

2023-08-14 · 22 minute read · Rust · code

Have you ever wondered what would happen if Crosswords and Sudokus had a baby? I know I haven't, but on a vacation in Lisbon, a Sudoku book in our flat introduced me to the concept of Kakuros:

Photo of a page of Kakuros of a Sudoku book on a couch in a flat in Lisbon

Like Sudokus, you have to fill all cells with the digits 1 through 9 and the same digit can't appear twice in the same word. Like crosswords, the layout is all over the place and you have clues. In this puzzle, however, those clues are not a description of a word, but the sum of the digits.

To get an intuition about how to approach a Kakuro, here's a tiny one:

2 4 13

Candy

2023-08-06 · 6 minute read · Candy · programming language design · university stuff · code

In statically typed programming languages, you define what values can go into variables and functions. Usually, you do this using types that are defined constructively – some types are built-in and new types can be created by combining other types.

Mathematical functions don't work on types, but sets. They are slightly different: Sets are defined by which values are inside or outside of them.

Constructive types vs. sets

Mathematical sets can be much more nuanced than constructive types. For example, you can define a set containing only even numbers. In most programming languages, types can't encode such information.

That's why we asked ourselves what a language would look like where functions work more like mathematical ones. The result is Candy – a programming language where requirements of functions are specified with normal code and checked during runtime.

Mehl: A Syntax Experiment

2022-05-21 · 5 minute read · programming language design · code

Roughly speaking, there are two ways to describe data transformations:

Most programming languages enable both styles of representing data transformations. On a small scale, those styles usually happen in the form of function calls or method calls, respectively. For example, here's a prototypical program that sums a list and then calculates the sinus of the result:

sin(list.sum)

Some function calls are written in a top-down f(x) fashion, others in a bottom-up x.f style. A few languages, such as Nim, even support a Uniform Function Call Syntax, so that you can use both styles equivalently. Other languages, such as Lisp, enforce one style over the other:

(sin (sum list))

Interestingly, almost no language enforces a bottom-up style. A notable exception is shell scripting, where it's common to use the pipe operator | to pipe data from one program into the next:

ls | grep foo

This resembles how I intuitively think about source code with lots of data manipulation. For me, the description "sum the list, then take the sinus of that" feels less complicated than "take the sinus of the sum of the list." Especially for longer function chains, the bottom-up approach allows you to mentally simulate the data flowing through the program as you read the code, while the top-down approach results in a mental stack overflow.

So, what would a programming language look like that enforces a bottom-up style?

Increasing Awareness of Energy Consumption in Jupyter Notebooks

2022-04-15 · 17 minute read · university stuff · code

Jupyter Notebooks are becoming an increasingly popular tool: These Python-based notebooks run in your browser and combine running code with writing explanatory documentation. Notebooks have a client-server architecture – even if they run on a powerful machine, you can still write your code on a light endpoint, such as a laptop. Free Jupyter Notebook services such as Google Colab make computing-intensive research fields more accessible to a general audience, but they also hide the amount of power consumed. If you're programming on your laptop, you might not even notice that the actual computing part requires a significant amount of resources in a data center. It doesn't help that Jupyter Notebooks are most commonly used in data science and Machine Learning, two of the most power-hungry disciplines. Hence, in my last semester, I developed an extension for Jupyter Notebooks that alerts you of your energy consumption.

The most similar extension is called Jupyter Resource Usage and uses psutil to retrieve data from the kernel infrastructure. That allows it to monitor RAM and CPU usage, but other resources are not supported – not even GPUs, which play a big part in training Machine Learning models.

Encouraging People to Be More Careful in Situations With High Infection Risk

2022-03-21 · 18 minute read · music · university stuff · code

As you might have noticed, we are currently in a pandemic. Luckily, there are several steps you can take to protect yourself and others: You can get vaccinated, wear a mask, avoid large groups of people, regularly ventilate when being indoors with others, etc. Some of these measures are easier to follow than others. Getting vaccinated is a one-off action, but remembering to open the window every few minutes is a lot harder if you also concentrate on something else, such as working or studying.

In the context of the Sonic Thinking and Neurodesign lectures at our university, I developed an app that continuously evaluates the current infection risk and turns it into music.

The aspirational goal of the project is to enable scenarios like these:

The Coronoise app takes incidence rate, number of people, and CO₂ levels as inputs and produces sounds.

Meta Strings

2022-02-22 · 2 minute read · programming language design · Candy · code

Most programming languages have the concept of a string, a representation of text in the program. In some languages, you can even integrate code expressions in strings:

"Hello, {name}!\n"

Special characters like { or \ indicate that the following characters are not part of the string literal itself, but should instead be interpreted differently – they are escape sequences.

This approach comes with some problems: Now, to use { or \ in the string, you have to escape those as well. This is okay but makes strings with lots of special characters ugly. For example, the regex that matches words ending with \ can be written like \w\\+, but inside a string, it becomes even more bloated:

"\\w\\\\+"

A Critical Look at Static Typing

2022-01-23 · 6 minute read · programming language design · Candy · code

Nowadays, there are soooo many programming languages. One critical differentiation point among them is how their type systems work. You can sort programming languages into two camps:

If given a choice, I prefer statically-typed languages. Because they know the types of variables, they can offer clever suggestions. Additionally, the compiler catches many errors while you write the code, so you get immediate feedback.

On the other hand, most type systems limit what you can express in a language. In comparison, dynamic languages feel more flexible.

Making MIDI Music with my electric piano and iPad

2021-12-29 · 1 minute read · music

I've played piano for a long time, but only recently discovered that my electric piano has a MIDI port at the back! Using it is a lot of fun: By connecting the piano to my iPad, I can play music through the iPad. This allows me to change instruments, and record and arrange music.

Piano connected to the iPad via MIDI

Templating engine? No thanks.

2021-11-12 · 2 minute read · this blog · Rust · code

Here is the Rust code that produces the page you're currently reading (at least at the time of writing). Some time ago, a friend of mine asked me why I used this home-grown templating mechanism instead of a standard like mustache.

Admittedly, this might look very hacky on first impression:

async fn article_full(article: &Article, suggestion: &Article) -> String {
    fs::read_to_string("assets/article-full.html")
        .await
        .unwrap()
        .fill_in_article(&article)
        .replace("{{ suggestion-key }}", &suggestion.key)
        .replace("{{ suggestion-title }}", &suggestion.title)
}

It's just loading the template file and then replacing some strings! (If you wonder about fill_in_article(&article), that also does nothing more than replacing some strings.)

Hacking the Gira HomeServer

2021-10-05 · 8 minute read · tinkering with the Gira HomeServer · code

Our home has an intelligent electric grid controllable using KNX. A Gira HomeServer connects to the physical KNX wires and our WiFi network and enables us to control all devices using an app. In my previous article, I looked at how the Gira HomeServer communicates with the app. As a reminder, this is how the authentication phase works:

comic

Reverse Engineering the Gira HomeServer

2021-09-12 · 8 minute read · tinkering with the Gira HomeServer · Dart · code

We have a pretty fancy home: There are extra wires in the walls used as a KNX bus – a system to control lights, thermostats, shades, and power outlets in our home. All devices and switches contain a microcontroller that can send and receive messages using the KNX bus wire. For example, light switches emit messages for turning a light on or off, and lamp sockets listen for those commands to turn the lamp's electricity on and off.

Compared to traditional cabling approaches, this is more flexible because switches can be added anywhere on the bus without requiring re-cabling – we could add a button that toggles lights on the other side of the house. Here's a comparison of how the cabling looks like:

Conventional multi-switch vs. bus system

On Developing This Blog

2021-08-14 · 1 minute read · this blog · Rust · code

I created the blogging server that hosts this page with my bare hands. Well, the HTTP request handling software at least. And I have to say; I thoroughly enjoyed it!

Why This Website Has No Dark-Mode Toggle

2021-07-18 · 3 minute read · this blog

Maybe you're wondering why there's no dark-mode toggle on this website.

Short answer: Misaligned incentives between layers of software result in an overall subpar experience. I want to put pressure on the browser offering to control the dark mode of individual websites.

Long answer: I recently streamed music from my laptop to a Bluetooth speaker and wanted to increase the volume. Naturally, I tried increasing the volume on the computer. Nope, it's already at the maximum. The Bluetooth speaker has volume buttons! Gotta try those! But except for the music being interrupted by one of these awful beeps, nothing happens. Oh, I know! Windows has an option to adjust the volume of individual programs that I use pretty frequently. I must have lowered the volume there. But nada. Finally, I checked in the music app itself, and fair enough, there's the volume slider, its knob almost on the left.

What happened here?

Chunky: A Database Layer

2020-10-09 · 5 minute read · Chest · Dart · code

Chest's lowest abstraction layer is called Chunky. In the end, Chest should somehow store all data in a file, something like 🌮.chest (yes, the taco emoji is a great name for a database). The Chunky framework will take care of managing access to that file.

A key question is how to deal with mutating data: If we need to insert some data "in the middle" of the database, we don't want to re-write everything that comes after it. Files are a linear stream of bytes, and that doesn't quite fit our use case. So, the Chunky layer offers an abstraction from that.

Chest: A New Database

2020-10-08 · 1 minute read · Chest · Dart · code

Databases are a fundamental part of most modern applications. Studying Hive interested me in database design, so I decided to implement a new database – called Chest.
I created it as a research project, but I'd also be happy to produce something worthwhile.