Computers are very complex machines. They can do almost anything and with time, the possibilities are only increasing.
The programs are created to accomplish a goal, a given task.
It’s impossible to build any program without relying on layers upon layers of complexity. Starting from the internal workings of the CPU, passing through the operating system and ending with the language itself.
Those complexities are there to help to accomplish the goal of the program. It’s necessary for using computers.
Then there’s the program itself.
Any non-trivial program requires building abstractions. The code itself would be too complex to comprehend to almost any human. Especially without any structure or organization. Changing anything would be a nightmare.
Those abstractions are there only for humans. Computers do not care.
Managing the complexity is necessary for building real-life solutions. Building abstractions is necessary to build more and more complex solutions.
Properly abstracted complexity makes it into a powerful building block, something which can be reused and incorporated into future solutions.
Building proper abstractions, at the right level and with the right dose of customizability is necessary in programming. It’s also one of the hardest things to do right, but when it is achieved the result empowers the creator.