On magic
I’ve been thinking about magic lately. It’s a concept in computer science where a programming language obscures the behavior of software in order to clarify its intention.
There are many forms of magic. Some are straightforward while others are downright magical. Operator overloading, such as a custom plus (+) implementation, is a simple form of magic. React tags can be functions or objects—you can’t tell which just by looking—which makes them magic. At the opposite end of the spectrum, domain specific languages (DSLs) can appear to rewrite a language’s grammar, and in some cases (e.g. C macros or compiler plugins) they actually might.
You can get into a lot of trouble debugging magic, so newer high-performance languages (e.g. Go, Rust, and Zig) deliberately avoid it. They are explicitly simple languages: fewer features makes them easy to learn and easy to debug. It’s easy to avoid mostly-harmless things, such as object creation, which can lead to unexpected performance penalties.
On the other hand, if the problem you’re trying to solve is inherently complex, such as UI design, a little magic can make the solution a lot clearer and easier to refactor.
For example, because React and similar declarative UI frameworks make functions and objects not just interchangeable but indistinguishable, you can start with a function and, as it becomes more complex, replace it with an object without changing the code which uses it.
I worry when developers brag about performance with UI frameworks. A lot of chatter on the internet is about which JavaScript framework is the fastest. Performance matters, but processor speeds are in nanoseconds (gigahertz) while human perception is generally in tens of milliseconds (millihertz.) If you feel the need to choose between Svelte or React based on performance, you probably have other bottlenecks you need to fix.
Swift is a really interesting language, in that it is both high performance and high magic. If you look at how it compiles SwiftUI from a React-like DSL into machine language, you’ll find that it’s turning a complex UI into a small number of mega-structs. That’s super efficient on modern hardware, but most developers would rather stare into the abyss than actually look at how it does that magic.
Perhaps that’s why Swift hasn’t caught on as a high-performance language outside of (and sometimes inside) Apple’s ecosystem. By default, it produces low-latency, memory efficient code. But it’s hard to trust that it’s doing the right thing—and if it doesn’t, it’s hard to tell what went wrong.