Here is what I mean. Implementing new functionality where nothing existed before is easy: just figure out what you want the machine to do, and tell it to do that. It isn't trivial, but on a relative scale, it's easy.
Precisely because it's easy to create functionality, we do a lot of it. Our programs grow. As they grow, they get complicated. As they get complicated, it gets to be more and more difficult to understand what they're already doing so that we can make them do something different. So, the less tongue-in-cheek version of my thesis here is that programming gets to be difficult because it starts out being easy.
This is why I always say that the essence of software engineering is the management of complexity. And this is the part that people who have not actually worked on large programs will probably never understand. (As someone once said to me, "what you need to get is that management views programming as primarily a clerical function".) Viewed one-by-one, the tasks seem simple. And yet, somehow, when you put them all together, they're not simple anymore.