Please stop calling it “magic” (2017)
zverok.space
zverok.space
As an example of jargon, the dictionary definition is irrelevant other than to emphasize that it is jargon. There are applicable broad arguments against jargon in general, of course, but as an example of jargon, it's not any worse than any other jargon term or phrase, such as "It's ____ all the way down."
If we want a definition that we can understand, the correct source is not the dictionary, but this quote from OG sci-fi author Arthur C. Clarke: “Any sufficiently advanced technology is indistinguishable from magic.”
With respect to programming, meta-programming is not indistinguishable from a spell cast by a mage in D&D. A better comparison is to prestidigitation, the entertainment art of doing a thing that appears to be impossible, even though everyone in the audience knows that there is a trick to it that can be explained and understood.
It's really that simple. "Magic" as a term of jargon means "A sufficiently advanced use of Ruby's meta-programming that is indistinguishable from a conjurer's trick to those who don't know the trick."
There are worse sins in programming jargon; like when you overuse technical terms so much that you lose the "point" of what it's supposed to do. Another one is using heavily overloaded abstract terms without explaining which variant you're thinking of. If you say "service" without context, I will come after you :)
"In Smalltalk, everything happens somewhere else."
I vividly recall that when I first installed Digitalk's Smalltalk/V, everything seemed to involve spooky action-at-a-distance.
Magic has a special form of non-locality. To look for the cause of "magic" one must either pray to some god or roll the dice and read the tea leaves. If hunting down the source of understanding feels like this, we call it magic.
Jargon can be carefully laid out and taught. Common practice can be learned and maintained.
Magic is a word invoked to intentionally tell you not to learn and to stop asking questions. It's insulting to the very nature of the programmer, who must ask these questions in order to understand the systems they are trying to describe.
As for the quote, which everyone has heard by now: "Any sufficiently advanced technology is indistinguishable from magic."
This is a cynic's perspective, which while valuable to a point, does not alone lead to that which we desire. We read this quote and think, ah yes, that is how I feel... I wish things were better.
"Magic" is in fact jargon, contrasting other meanings of the word with jargon itself is irrelevant to that.
This was my primary challenge.
Either you accept everything as jargon, or you actually read my reply and consider my perspective. I'm not offering a crisp definition, I'm merely adding some addition flavor which is at odds with the parent's as I understand.
In that sense, it does not imply "stop asking questions," nor does it imply "there is no answer." To me, it implies, "This may look like a supernatural entity is involved, but that's just a trick we're pulling. If we pull back the curtain, we'll find there's a little man with some levers and we'll see how it's done."
Tricks are fundamentally shocking and uncomfortable at first. Many people like this from time to time, but it shouldn't be the intent of our programs.
The programs should be written in a way that helps the reader learn. If that involves some clever reveals and abstraction / hiding then so be it. The best lessons are taught in stages.
They're mystifying at first, then you learn how to use them without looking under the hood, then you learn exactly how they work, then you start making your own.
The word "trick" is associated with prestidigitation. Unless you're entering the Underhanded C context, these "tricks" are more like magicians showing EACH OTHER how to do things.
"Here's how to make flowers appear out of your top hat."
"Ah!"
The whole point of science is separating the magic that works from the hocus pocus that doesn’t. Just because you understand it, just because we have equations, algorithms, and stories that explain the relationships between things, that doesn’t mean it’s not magic. It just means the magic is REAL.
It’s impossible for me to look at a computer, a server rack, a car, or a roomba and not see the magic. Just because I understand the principles behind them doesn’t rob me of the wonder of the universe.
The analogy I like to use is Hogwarts. Just because they study spells in that fictional world, just because they have schools and universities doesn’t mean the spells aren’t magic. They’re studying the magic available to them in that universe.
Thank you for reminding us of the everyday magic surrounding us.
> If you ever code something that “feels like a hack but it works,” just remember that a CPU is literally a rock that we tricked into thinking. Not to oversimplify: First you have to flatten the rock and put lightning inside it.
Neither of those are super closely linked to your comment. I just think you might get a kick out of them.
I 'understand' (more so then) them of course, the theory, the practice, but what magic that any of this works?!
Maybe it's just because we can't see it, and it oughtn't be any weirder than anything else, but I still find it nuts and have to try not to think about it too much. Nevermind the crazy bandwidth & latency & distances we've come to expect with the internet.
The idea of an atom, or a quark, is a construct that approximates reality. Nature doesn't care about our constructs. Just because we've kinda "figured it out" doesn't mean we've robbed nature of it's magic. We are only discovering the magic that was always there.
And, IMH(umble)O, the magic we discovered since the Renaissance is far cooler - far more magical - than anything the Alchemists could come up with in their wildest dreams.
I can appreciate how Lightroom works, or an electric car, or the electrical grid, etc. I don't have to know every last detail, but I should have some awareness of the fundamental principles on which these things are built.
Deferring this to "magic" in the sense that I say "I don't know how that works, no one can know, it's MAGIC" can be a lazy way to think. I think it's a slippery slope that gets us closer to psuedoscience, new-age gimmicks, and other forms of poor thinking and manipulation. We should all seek to understand how things really work (even at a coarse level) in this Demon Haunted World of ours.
(Even if this isn't how you interpret this word, I'm suggesting there is a risk that others do).
But for us working in it, who can see the layers upon layers of abstractions, it feels less magical and more like a miracle that any of this works at all.
Many of the devices you mention are programmed at such high levels that the programmers themselves rarely understand exactly what's going on beneath the surface. The hardest part of getting the thing to work at all is managing the complex web of dependencies underneath, not programming the actual functionality. Systems that appear magical are mostly running on a house of cards and person-years worth of frustration.
In python, if I see `print(5)`, I should know what that will do. Now, it's possible to do all sorts of magic and make it do something different (like print "five"). The reason that hijacking `print(5)` is magic is because when I look at it, I have reasonable expectations that are subverted.
The reason that magic is often considered bad is that if my code is supposed to subvert my expertise, then my expertise suddenly isn't useful to getting my job done. If I want to make it do something else, or debug it, I won't know where to go, because I should know how to debug `print(5)` or change it to `print(6)`, but now I don't know my way around my tools.
Maybe it's a connection to black boxes. If a reasonable user can't see how or why your magic works, and can't debug or direct your magic, it's too magical. Yes, that's subjective, but too bad. Maybe "opaque" is a better word.
The author's point seems fairly clear to me: there are some types of metaprogramming where the "why" is reasonably discoverable, and other types where it is not. "Magic" is often used as a derogatory umbrella term for any kind of metaprogramming, but in fact we all use metaprogramming on a regular basis, and generally the umbrella term is used to disparage metaprogramming that I, the center of the universe, am not familiar with.
I think the point is well-taken. Much of programming is metaprogramming; it's a matter of which parts you've familiarized yourself with and which you haven't, and it dumbs down the discourse when people misuse the word magic to describe discoverable forms of metaprogramming. It would be better to specifically critique individual forms of metaprogramming so that we can have productive discussions about those forms.
From this perspective, discoverability isn't sufficient to claim that something isn't magical. What's magical is that it's sufficiently complicated and reliant on other sufficiently complicated things that -- in practice -- no one utilizing it will bother digging that deep.
These things are only knowable in the hypothetical. In practice, they're arcane incantations with rigid, arbitrary constraints that must be respected for the system to function as you'd like.
The FA does seem to specify a particular frustration that my pithy quote doesn't address
>>"It is common to see nowadays statements like “this is too magical for less experienced developers to understand”. As Matz says (reciting from memory), “Ruby is complex language to make developer’s life simple”, not the other way round.
>>Your car’s engine and your computer’s processor are pretty complicated, too, but that doesn’t mean that they are “magical”. Neither that you shouldn’t use them and stick to “less magical” solutions."
I think this is a separate point but it is one I agree with. Probably some nuance here, but I think the problem is less that something is seen as magic and more that something might be prematurely hobbled.
To me this is an adequate description of most of the software 'tricks' presented to me as magic.
Wait wait wait... are you telling me that David Copperfield didn't use "rituals, symbols, actions, gestures, and language with the aim of utilizing supernatural forces" when he made the statue of liberty disappear?
The thesis of the article is that, especially in Ruby world, we use the term 'magic' too much, when it's really a derogatory term that applies to cases where it's particularly hard to intuit _how_ a particular piece of code works.
In the same vein, there are plenty of operations that can be done with arithmetic only (obviously not magic, right?) whose purpose is completely incomprehensible to anybody who didn't write it. Most of these will also be incomprehensible to the author after a period of weeks or months. The same goes for complex sed or regex expressions or a million other one-liner tricks that we nerds love so much. Even if I don't expect anyone other than myself to ever read the code (no, make that especially if it's just for me) I write a brief comment with some explanation of what it does. Or maybe wrap it in a semantically accurate function.
I did a little bit of Ruby/Rails about 10 years ago, and this article also reminds me why I have avoided Ruby since, coming to down to this (non)quote:
> As Matz says (reciting from memory), “Ruby is complex language to make developer’s life simple”, not the other way round.
Ruby claims to make the developer's life simple by being complex, which in my opinion is just backwards reasoning. You lost as me at "parentheses are optional". I'm not even a Python guy at all but I'll go back to my favorite truism from the Zen of Python: explicit is better than implicit. Give a team of nerdy programmers too many routes to the same goal and you're guaranteed to end up with a bunch of code that nobody understands.
The Zen of Python is more of a meme than a list of guiding design principles of the language. This explicit over implicit one in particular.
Python does things very implicitly. It encourages operator overloading, so you're never really sure what `a + b` does without seeing the `__add__` implementation. Same for `len()`, `str()` and a few others.
Metaprogramming is also considered an advanced topic and used extensively in the wild.
Python programmers love implicit behavior and building abstractions that hide the complexity away. It's kind of what the language is about, so being explicit over implicit is rarely followed.
Similarly for the other points in the Zen. "There should be one obvious way to do it" is an internal joke; the Dutch line following it is the punchline. While it doesn't follow Perl's extreme TMTOWTDI mantra, there are often many non-obvious ways of doing the same thing in Python. See `str.format()`/`%`/f-strings, for loop/comprehensions, enum implementations, the packaging mess, etc.
A language that follows explicit over implicit and one way of doing things is Go, where you're actually forced to do things a certain way because of the design simplicity. Granted, not everything, as generics are now a thing, and modules were a mess for a long time, but it mostly follows Python's Zen more than Python.
> That’s an example of “supernatural” behavior: e.g. when something happens not being obviously related to natural forces of the language. …And is bad exactly because of this fact: your natural tools and intuitions stop working, you need just to remember entire spellbook to deal with magical code.
The words natural and spellbook could probably map onto idiomatic and confluence. lol
I like it because magic code isn't bad, or slow, or unclever, it is often magic to achieve the opposite. But it does lack something like "being plain spoken"
https://www.cs.utah.edu/~elb/folklore/magic.html
Edit: it is in the jargon file, just like I remembered it:
It represents things that happen that you don't understand how they happen. Not just you don't understand how they work when presented with the effect, but is resistant to being reverse-engineered.
In your typical programming environment there are ways to backtrack through code searches, type hierarchy management/overloads, interface implementations, type definitions, recasts, scope resolution, etc that you can deconstruct some "magic incantation" to figure out where it is calling and then what it is doing.
In dynamic languages (the article is about Ruby) this gets a lot more dicey, with duck typing, lack of strong typing or optional typing to enforce / document what types are being used where, sometimes dynamic scoping, macro expansions.
In those cases, IDEs are you friend in a BIG BIG way. They enable targetting searches, parsed/contextual navigations, type guessing even for some dynamic languages. IDE+static-ish typed languages is even better: back navigation to the type, navigate up the type hierarchies or compositions.
E.g. a "magical vacation" doesn't involve casting spells...
Likewise "magic" in a program doesn't mean we can't ever trace where the effects we see are coming from. Just that they were put in with metaprogramming, and not more conventional methods.
This is my definition of magic: when it _does_ so
That's my pet peeve with Rails and Rails-minded gems, which do such magic as a core tenet. Someone ends up being too smart for their own (and others) good, it looks lovely and clever from the outside, methods are added to core objects, often dynamically so, global-like state is rampant, lazy behaviour is pervasive.
Then something breaks, and you're left with behaviours that make no sense. Of course with enough time and energy one can see through the veil by diving deep in the bowels of the framework, but I don't quite like the thinly veiled judgemental statement of TFA that magic is just metaprogramming and that as a dev you should get your shit together, which does not help in the real world when all hell breaks lose in nonsensical ways because a prime directive has been violated†.
Tricks and prestidigitation have no business being used in systems that aim to be reliable.
† Blindly copying references to thread locals into another thread[0], assuming every possible one ever used in all apps and dependencies is either scalar (which they're usually not), deep-frozen (which they're usually not), or thread-safe (which they don't need to be, because they're, you know, thread local), can only be delicately described as "a bold move".
[0]: https://github.com/rails/rails/blob/6ec669b65d5cd47c98466192...
This differs from abstraction, which is fine. Abstractions are the bread and butter of programming. But if an abstraction is too leaky, or it interoperates badly with other abstractions applying to the same code... It ceases to be abstraction and becomes spooky action at a distance.
You could implement subclassing in a language via an inheritance chain or you could implement it via taking objects and replacing their various methods and fields with other methods and fields after they've been constructed. One is the object inheritance abstraction. The other is spooky action at a distance.
> What's not magic
> What junior does not understand, is not magic
> Monkey-patching is not magic
> Metaprogramming is not magic
I've noticed this especially in the Rails community to talk about functionality they find fascinating and which either they don't understand or don't want to explain.
Like, when a design is magical, that means it has effects that aren’t fully understood. Like architectural decorations on buildings have real effects on the vibe of a neighborhood but we really don’t understand the specifics of how or why they affect us psychologically.
I also agree that the site is hard to read w/ grey text on a white background.
Dictionary.com definition Magic: NOUN the power of apparently influencing the course of events by using mysterious or supernatural forces: example: "suddenly, as if by magic, the doors start to open"
I'm a big fan of Ruby, and feel like I know the language pretty well, but, my goodness, I don't know how I've never come across this one before. THIS is something that feels like magic!!
[1]> 3.method(:days).source_location
=> [".../lib/active_support/core_ext/numeric/time.rb", 37]
[2]> puts 3.method(:days).comment
# Returns a Duration instance matching the number of days provided.
#
# 2.days # => 2 days
=> nil
[3]> puts 3.method(:days).source
def days
ActiveSupport::Duration.days(self)
end
=> nil
https://ruby-doc.org/core-3.1.1/Method.htmlStuff like `Foo.find_by_bar`
When all you did was define a db table "foo" with a column "bar".
In the early days of Rails, that WAS magical! PHP certainly couldn't do that. I'm not sure how advanced Java's retrospection was in those days. But it seemed as though Ruby/Rails was the only (popular) language around at the time with that sort of trick up its sleeve.
Personally I tend to use “plumbing”. It’s important, has a tangible result but it’s working are totally hidden unless you go looking for it.
I like to say to people that a good framework has a lot of plumbing, where others might call it magic.
"What junior does not understand, is not magic."
To that, I say the difference between a mid-level and senior is that the senior knows "magic" actually is bad.
'Magic' is, when things – after proper enchantment and ritual – sometimes happen as expected. But you cannot explain why (other than 'because of proper enchantment').
I guess we got, what we called for.
This is not exactly news, there are whole guidelines on contrast published and backed by copious research.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/U...
I understand that some people are unaware of this issue. For those that are open to becoming part of the solution when it is brought to their attention, I hold no resentment.
But for those that belligerently minimize the problem, for example characterizing the challenge as "I don't like how this website looks"... not so much.
Same with organizations that surely know better but continue to present problematic low-contrast interfaces. (Discord, I'm looking at you.)
People with disabilities often will not lead with, so I have this condition. They'll just say they are having a hard time reading your site/the fonts are too thin/the contrast is off.
If someone is saying your site is hard to read, listen, because many others are having the same problem.
If I really want to read something like this I usually copy it into a text editor (usually Sublime).
.post {
font-family: unset;
}
.wrapper > center,
.site-description,
.site-navigation,
#disqus_thread,
.postNavigation,
.site-footer {
display: none !important;
}