Recently there has been a lot of talk about “magic” in software. Most of the people doing the talking, however, seem to be talking past one another, primarily because they do not share a common understanding of what “magic” means. The few definitions of the term I have seen seem to miss something essential, so I will provide the definition that I think makes the most sense:
In a software system, magic is any behavior whose semantics is poorly defined and unduly expensive to figure out.
- The “unduly expensive” part means that people with different background knowledge are going to find different things magical. If you use certain techniques every day, you will probably find behaviors that make use of those techniques easier to figure out and thus less magical than other programmers might.
- One way, then, to make things less magical is to exhort programmers to get more knowledge. A more practical approach, however, appears in the next point.
- Most “magic” can be de-magicked simply by defining its semantics.
So when I complain about magic in a software system, I am complaining about code whose behavior is not readily discernible. When I did a lot of Rails programming, for example, I groaned when I encountered a function in the Rails API that took a string but did not make clear what that string was supposed to represent. Was it text? Was it HTML? There was only one way to find out: trace through layers of Rails code to figure out what the framework actually did with the string. That is unduly expensive, so I considered such functions to be magic - annoying, waste-my-time magic.
I do a lot more Python programming these days, and while I encounter less magic, I am mystified by the part of Python culture that turns its back on code that is perceived as being overly clever or, to use the popular phrase, not explicit. What is wrong with cleverness, as long as the result is clearly understood? Cleverness, by itself, is not magic. For real magic, you need fuzzy semantics, too.
That is why, when I hear that code is “magical” or “too clever,” I think “poorly defined.” If you define and document the semantics of such code, you dispel its magic. And if you cannot define the semantics, then the code is magical and too clever, and probably ought to be rewritten.
Thus the test for whether something is magical is the clarity of its semantics. Code having clear semantics is not magical. Code having unfathomable semantics is.