Pangram verdict · v3.3
We believe that this document is fully human-written
AI likelihood · overall
HumanArticle text · 1,895 words · 5 segments analyzed
Interview With Matheus MoreiraJul 2026 - Alex AlejandreMatheus Moreira (blog) built lone lisp directly on Linux system calls. In this interview, he shares his knowledge of C and the Linux Kernel.How did you get into computing originally? What was your path before discovering Lisp etc.?I’ve always liked computers, but what truly got me into programming was video games. When I was a kid, I used to play games from a series called Mega Man Battle Network, and I ended up getting inspired by those games. They’re ultimately responsible for my learning English; I used to join forums as a non-English speaker and try to socialize. It was rough at the start but I improved! The same goes for my first language, C++.How young were you when you started with C++?In Brazil there are “technical schools” which is what I attended. They’re normal highschool curriculum, with extra professional classes. I’m not sure if these are common abroad, if there is a term for it. There were other courses, also: chemistry, mechatronics… As for quality, it was basic, yet pretty good for a highschool level. It did make me start learning all by myself though; within 6 months, I’d already learned the entire curriculum. Eventually they hired me as a teacher’s assistant to help fellow students.So when I started highschool, around 13-14, I took the informatics course and started learning C++ with a very old IDE called Dev-C++, which still exists on source forge! I also browsed the tutorials on cplusplus.com. I tried making games but wasn’t very successful at it! It was pretty hard, especially because I had yet to learn all the physics I was supposed to be simulating :) What I did end up doing was learning a lot more languages. After some basic C++ proficiency, I learned quite a bit of Java, then Ruby, then Python… That eventually led me to Lisp and Scheme! I remember thinking scheme was extremely elegant when I first saw it. Ruby was my favorite language though. I wrote a few gems back then. I think one actually got a small following: Acclaim, a git-like command based argument parser.
Cool! Did you happily jump into new languages or did you first try to stay with C++?I think I started learning more languages after I exhausted the cplusplus.com tutorials. I felt if there was nothing else for me to learn on that site, then I should probably move on, right? Sun used to have a really big Java Tutorials website back then. I think I read that entire site. That was when I learned object-oriented programming. I wrote some java code as a teenager… Some “utilities libraries”. In hindsight, it was just a badly implemented version of 1% of what Apache commons has! I think I even published it, might still be out there somewhere… I also remember experimenting a lot with Java Swing applications. I used to really like the Nimbus look and feel and made a circle/arc drawing application for my math professor once.What motivated all of these delvings? What inspired you to keep checking out different languages and so on? Have you stuck with Ruby too?School projects were a big motivator in my early school years, but at some point it was about curiosity, and a desire for The Right Thing. I wanted a language to call home. I stuck with Ruby the longest. It’s a really nice language. I always have it installed, and have recently started a Rails project! But it has its imperfections too. The other language that I stuck with was C. Its low level simplicity was really captivating to me.I didn’t forget C++, but I also didn’t update my knowledge. Current C++ is essentially a completely new language, so I no longer claim I know C++. In a sense, I replaced it with C. C was always captivating for some reason, despite all the problems and legacy, but it really started getting entrenched in my mind when I started exploring the CRuby VM source code as a teenager. I had this really fun past time where I’d watch for interesting stackoverflow questions where someone would ask “why does Ruby act like X?” and I’d dig into the source code to figure it out.A few years ago I tried to transition to Rust, but it didn’t quite stick. I’m also a huge fan of Zig and its creator.
Have been since I watched “the road to Zig 1.0” keynote where he laid down reasons why people “rewrite things in C”: speed, ABI…What pros and cons kept you with C and Ruby?Ruby was an extremely expressive language which “just fit” with my mental model. I could often guess a method name and it would work. It has nice things like singular/plural forms of method names, synonyms. Our brains work with these words, and Ruby supports them all.Matklad mentioned good APIs should be guessable and if he guesses stuff which don’t exist, he’ll often file a bug report saying the API demands it!Ruby also enables composing eerily shell-like processing pipelines… items.each.with_index.map… It just keeps composing and you can do a LOT of work with very few characters.For C, the main advantage is the simplicity of the output. You write a function, it compiles to an ELF symbol and associated assembly code. They say you can see the compiler output when you write C, and it’s true. With C++ the compiler adds a lot of machinery, it’s very difficult to understand how it all fits together. With dynamic languages, it’s just the same, but I found it easier to explore the source code of virtual machines than that of compilers.So your C++ style changed, removing sugar until you were writing C?Yes. My style also changed as I read more and more code written by other developers. I’ve explored CRuby code, CPython code, JVM code, a bit of guile code, even a bit of V8 code… I started to really admire expert C programmers when I started reading Linux kernel source code though. It’s really good, probably the gold standard.From the beginning, you read a lot? It’s quite rare particularly today for people to really read others’ code. How do you approach this? Any tricks or techniques?I read a lot. I’ve always been the sort of curious person who wanted to know how the thing worked. I wasn’t satisfied with just using some library, I wanted to know what it was doing under the hood. I wanted to know how the drivers talked to the hardware. I wanted to know all the hidden fun stuff. That’s just the sort of thing that’s interesting to me. The real applications I tried to make, I’d end up digressing into these unrelated explorations.
Other programmers would tell me “why waste time on that? it’s already solved” but I wanted to know how it was done, and eventually I also started to develop a sort of hubris that led me to want to reinvent the wheel, but better.I did get the message though. I felt like I was a bad fit for a career in software development because of this quirk, so I didn’t pursue one in the end. Kept it as my hobby to this day.When you first looked at driver code, how’d you make heads and tails of it all?I couldn’t make heads or tails of it all… at first. It was frustrating, but I kept persisting and eventually I was able to understand some things, at least. I’m no hardware engineer, that’s for sure… But I managed to reverse engineer some of my laptop’s features. Still one of my proudest projects. My laptop is one of those Clevo barebones models. It has a pretty nice keyboard with RGB LEDs, most individually addressable. There was a REALLY bad windows app to control those LEDs. I swear it took over a minute to show a window on the screen, it was really aggravating. I used wireshark to intercept the USB packets it was sending to the keyboard and write a linux user space driver for it. I captured the packets, stared at the screen until I figured out their structure, and wrote a little C program to configure the keyboard for me. Threw it out on github and forgot about it… One day I went back there and somehow people were using the thing, one person even made a GUI for it. It was a pretty good feeling. I learned more about drivers and computer technology from trying to reverse engineer the rest of the laptop’s features. ACPI power management stuff. I didn’t quite figure everything out though, to this day.You have an article about linux system calls, was that the moment you took the lone direction?The code for system calls is pretty minimal, they work like normal function calls. I’d say the interesting part is that it allows you to bypass libc and target linux directly. Linux is famous for user space ABI stability; userspace components not so much. It allows people to depend on Linux kernel directly, without other things in-between.I started with this general sense that people didn’t want me to use them.
I’d read the manuals and they’d say things like “this system call is not supported by glibc”. I’d read wikipedia and there’d be an infograph is howing glibc wrapping linux, as though it was the CRT of Linux and other libcs didn’t exist. Then I read an article on the LWN about how it took like two years for the getrandom system call to show up on glibc.CRT?C runtime. The standard C library: glibc, musl, uclibc.It’s that package which breaks the entire world whenever they break compatibility. Because everything depends on it. I remember the article mentioned something like “maybe Linux should have a liblinux.a with just the syscalls, then people can bypass libc when they aren’t helping by just passing -llinux to the compiler”. I thought that was a really cool project idea so I went and created liblinux, which was just that: a collection of linux system call wrappers for freestanding C programming. It turned out that it was really fun to program against the Linux system call interface. So many of C’s problems just disappear in freestanding mode.What C problems disappear in freestanding mode?The most basic one: errno. C has this notion of a “current error” which is a global variable. Every function sets it, and you’re supposed to check it. Linux just returns you that error like a normal function would. The C libraries take that value, and put it in a global variable. It’s just the way things are in C. Not in freestanding C. The legacy of C also disappears too. The C library has a lot of legacy code in it. The locale stuff, for example, is extremely problematic. It’s also global state (a recurring theme!) which can cause very subtle errors based on things like environment variables. Liblinux taught me freestanding C, and how clean C could be… If only we could delete all of its legacy. It was painful. I had to write all of my own functions. From basic bytes copying functions, to integer->string conversion functions… The problem turned out to not be as insurmountable as I imagined though, and I persisted. I knew that when in doubt, I could always read code. I could see how the giants before me did it.