Abstraction is not just about hiding code - its about reducing options. You purposefully reduce options to make the system easier to reason about. A "function" in a programming language is an abstraction over machine code. It looks like variables have scope in an isolated environment, and it looks like the braces mean something, but it's compiled down to machine instructions that have no such concept. Goto considered harmful, but compiled machine code is littered with jump instructions (of course). You can do a lot of funky tricks with machine code that the higher abstraction of a programming language doesn't let you do. When you create an abstraction you reduce options for the user of that abstraction. So abstractions tend to gather cruft over time because users want those restrictions relaxed to do their special thing.