Printf wasn’t always there. Before it, you wrote to stdout directly. Before stdout, a syscall. Before the syscall, you poked bytes into a memory-mapped display buffer. Before the memory map, you flipped switches on a front panel and watched lights blink back.
Every layer down, someone built something so the next person wouldn’t have to. That’s the whole field. Languages we didn’t design, compilers we didn’t write, protocols we didn’t invent. We’ve always stood on a stack of other people’s work and called the output ours. Nobody ever had a problem with that.
Someone wrote printf. We used it – no disclaimers, no guilt, no explaining that we could’ve done it the hard way. Same with every layer that came after. I didn’t build the regex engine my code imports, or the TLS library that negotiates every HTTPS connection I ship, or the garbage collector that runs under every service I’ve written in the last ten years. Nobody ever asked me to apologize for any of them.
Every previous layer still asked you to think in the problem’s language. C didn’t give you a program unless you understood memory. SQL didn’t give you the right rows unless you understood the relation. HTTP didn’t give you a response unless you understood the shape of your request. You could be bad at any of them – everybody was, at first – but the tool didn’t hide it from you. It gave you errors, or worse output, and you had to learn your way out.
The newer layers are different. For the first time, you can get output without having gone through the thinking that used to produce it. The tool can deliver what you couldn’t deliver yourself, and it can deliver wrong output that looks exactly like right output. Most people still think first. But the option to skip is new, and that part is new in a way nothing else has been.
Whether the tool counts was never the question – it always did. When the output looks right but isn’t, would you know? Could you find it? Could you fix it?
That’s just the part that didn’t change.
