In programming, there is this phrase that’s often thrown around: too much magic. It’s a derogatory phrase; it loosely means that something is trying to do a lot for you, but is hard to understand and therefore scary. And that’s not necessarily wrong! The more something does for you, the less you understand, and that can be bad.

But also… isn’t that what programming is all about at some level? Not having to understand how everything works is how stuff actually gets done. What if “Intro to Python” started with: Let’s learn about how transistors work. Then we can build logic gates and eventually CPUs. After that we’ll build an OS, and then a compiler. And maybe in a few years we’ll be at the point where we actually know what happens when you write

print("hello world")

As a brief tangent, the steps I outlined above loosely follow the syllabus of an amazing book/course Nand to Tetris that I highly recommend. But even that needs to start somewhere! And it starts by assuming the existence of a nand (not and) gate. How does that work? I dunno, physics.

I think another word for magic is abstraction. Abstraction is not understanding how something works, but still being able to use it. It’s like blurring your eyes a bit and saying: Ok, I don’t totally understand how this works behind the scenes, but I see it has a green button to start it and a red button to stop it and that’s enough for me right now.

But abstraction is good and magic is bad. Why?

At some level, it’s definitional. I think one could define magic as “leaky abstractions”. A leaky abstraction is one where you kinda do need to understand how it works. In other words, it’s an abstraction that’s bad at its only job: letting you not understand the details. Leaky abstractions leak some details that are supposed to be abstracted away.

Anyways, I’ve been thinking about all this in the context of a new UI framework that I’ve been learning called svelte. Overall, it’s kind of amazing. It does so much for you and makes everything so easy. It’s like magic.

However, that magic came back to bite me yesterday. I wrote some code and it didn’t work as I expected. The details aren’t really that interesting, but if you care, I was trying to access the value of a svelte store using the $ syntax and my store had a value of undefined, even though I had provided an initial value. So I did what any programmer does: I tweaked the code in a myriad of ways to see which versions worked and which versions didn’t to give me some intuition about what was going on behind the scenes. Already, this is sounding a bit like the bad kind of magic. I had something that normally “just works” and all of a sudden it didn’t, and now I need to understand the details.

Eventually I whittled it down to a minimal reproduction where I had two version of the code: one that worked and one that didn’t. And the only difference between the two versions was whether or not the <script> tag had lang="ts" or not! 🤯

This is the bad kind of magic. The kind of magic where if you look at it the wrong way, it stops working. This kind of magic is how developers become superstitious. You can’t do X. Why? I’m not sure, but when I do X my code stops working and I’ve never been able to fully understand why.

This is particularly ironic because overall I’m quite enamored by svelte and so I’ve mentioned that I’m learning it to a few people. And one of their responses was effectively: Yeah, it does look really cool. It’s just a bit too much magic for me. Up until yesterday, I hadn’t felt that. Now I have.

I’ll end with two important caveats:

  1. I’m new to svelte, and there is very possibly a good explanation for the crazy behavior that I’m seeing. The problem might be between the keyboard and chair.

  2. I’m still really excited about svelte! Everything has a few sharp corners and I’m not going to give up on it just because I ran into one.