I’m on a mission to find the fastest way to copy and delete files on a modern machine. I thought a quick Google search would reveal the answer, but I only found this Stack Overflow post with people’s opinion on the matter (but no proof), a discussion on what the kernel can do to improve performance, and various articles claiming you should tar directories to copy them faster (there’s no chance of that being faster than a properly written parallel cp implementation).
The only way to get an objective answer is by writing benchmarks, so here they are. 😁 The results will be highly dependent on your specific system, so I would recommend simply running those benchmarks yourself if you’re curious. However, I’ll share my findings from running these on my ext4 XPS 17 and an APFS Macbook.
You might have heard people say that functional programming is more academic, and real engineering is done in imperative style. I’m going to show you that real engineering is functional, and I’m going to illustrate it using a computer game that is designed by engineers for engineers. It’s a simulation game called Factorio, in which you are given resources that you have to explore, build factories that process them, create more and more complex systems, until you are finally able to launch a spaceship that may take you away from an inhospitable planet. If this is not engineering at its purest then I don’t know what is. And yet almost all you do when playing this game has its functional programming counterparts and it can be used to teach basic concepts of not only programming but also, to some extent, category theory. So, without further ado, let’s jump in.
A lot of ink has been spilled about configuration file formats. Popular formats like JSON, TOML, YAML, and XML each have their advantages and drawbacks. There’s an alternative that should be receiving more attention: Typescript!
A lot of people ask us the question, why do we choose to use Common Lisp as our primary development language? Often times the question comes disguised as a suggestion: “Flask is a great webserver you should consider using”. This is a well intentioned suggestion- of course we would like to use the best tools available! Below, we’ll do our best to explain why we use Lisp, and why we think it is the best tool for our needs.
This is a difficult question to answer, because without knowing Lisp and the concepts from the language, it is impossible to deeply explain the benefits of said language. In the following article, we’ll discover and briefly examine what makes Lisp a powerful and relevant language over 60 years after its conception.
I’ve been building a “document development environment” called Programmable Matter that supports live code embedded in documents, with a simple TypeScript-like programming language. It’s been fun figuring out how to implement it—the type system in TypeScript is unusual and very cool!
I want to dig into what’s cool and unusual about TypeScript by presenting a type checker for a fragment of this language (written in actual TypeScript). I’ll start with a tiny fragment and build it up over several posts. In this first post I’ll give some background to help make sense of the code.
gotostatement is universally revered and can be here presented without contest.
In this programmer’s opinion, you should use whichever constructs leads to the best code, factoring in maintainability and speed. And sometimes this might be
In this chapter, we’ll see how
gotoworks in C, and then check out some of the common cases where it is used157.
C++20 added minimal support for coroutines. I think they’re done in a way that really doesn’t fit into C++, mostly because they don’t follow the zero-overhead principle. Calling a coroutine can be very expensive (requiring calls to new() and delete()) in a way that’s not entirely under your control, and they’re designed to make it extra hard for you to control how expensive they are. I think they were inspired by C# coroutines, and the design does fit into C# much better. But in C++ I don’t know who they are for, or who asked for this…
Andrej has invited me to write about certain surprising functional programs. The first program, due to Ulrich Berger (1990), performs exhaustive search over the “Cantor space” of infinite sequences of binary digits. I have included references at the end. A weak form of exhaustive search amounts to checking whether or not a total predicate holds for all elements of the Cantor space. Thus, this amounts to universal quantification over the Cantor space. Can this possibly be done algorithmically, in finite time?
I decided to try running Mezzano on real hardware. I figured my Librebooted ThinkPads would be good targets, since, thanks to Coreboot and the Linux kernel, I have reference source code for all the hardware.
On boot, these machines load Libreboot from SPI flash; included in this Libreboot image is GRUB, as a Coreboot payload.
Mezzano, on the other hand, uses the KBoot bootloader. I considered chainloading KBoot from GRUB, but I wondered if I could have GRUB load the Mezzano image directly, primarily to save a video mode switch.
Working as a professional software engineer can be tiring: you’re often working on a small part of a larger system, making small changes and fixing bugs. Over time you also learn to rigidly follow best practises: write code that is efficient, document your functions, always check error codes, etc. It’s easy to forget the fun of just programming and the satisfaction of creating something.
I set out to try to reclaim some of that fun by setting myself a challenge: implement a Lisp interpreter in a weekend. How much could I achieve? I wasn’t sure but I figured it should be achievable. The nice thing about Lisp is the lack of syntax, meaning that parsing of the program text isn’t difficult. But there are still lots of other things to take into account. I was also curious as to how small (in terms of lines of code) a Lisp interpreter could be.