What time is it?
Is it time to become a know-it-all programmer or is it time to become a productive programmer?
Knowing the abstraction layers that exist below those among which you work is a good thing, it grants you a better understanding behind the structure of your work and it will even allow creating better solutions.
Yet, you do that, you study when it is not the time to be productive. When it is the time to be productive you take high level tools and build with them. Using all the knowledge you have of how things work, and expressing the solution in terms that makes sense to the problem space.
Of course you would be required to know to use such tools, there is the tradeoff of the time it takes to build with a poor tool vs the time to learn to use a more appropriate tool. That's beyond the scope of this question. Yet, you understand that there is an advantage in knowing diverse tools.
Until now, I always believed that you should learn programming languages that makes you do low-level stuff (e.g. C)
It is not that you should, it is that it is a good thing to know low-level stuff.
to understand what's really happening under the hood and how the computer really works.
First off, you don't need a programing language to have an appreciation of how the computer works. Second... I'm afraid that C may be too high level, and a bit narrow. C is a good mapping of an old version of the hardware architecture, made abstract enough to be source portable to different systems. If you want an in-depth understanding you should aim for assembly language (note that assembly language is an abstraction of machine language).
Eventually, I thought you will become a better programmer knowing this
Yes, you will become a better programmer by knowing that.
Because you'll know what's happening rather than assuming that everything is magic.
You don't need to know how things work to know they are not magic. All you need is an appreciation of how they work, what are its costs and what to expect from it.
And knowing low-level stuff is much more interesting than writing business programs, I think.
Well.... low-level stuff is interesting in the sense that they are thought provoking and inspire curiosity. Business programs may deal with another meaning of interest, one related with money.
Besides, you may be under the impression that all business programs are pretty much the same: some database, some model classes, some CRUD, etc... Those are the boring ones. But look how diverse software is, and how diverse are the business around them. Do not constraint yourself.
My goal is to become a better programmer, to understand computer science more and this got me really confused.
If you want to become a better programmer, you will learn to write reusable code. Because having code that you can trust to work and you don't have to write again each time will make you more productive (as in: doing the same task in less time, but also as in: having less bugs). If you do this, you may be interested in placing your re-utilizable code in a re-utilizable and sharable format... and maybe even share it with other developers. If at least you even consider doing this, I hope it will develop an appreciation for re-utilizable code shared by others, an appreciation for the usefulness of development tools, and an appreciation for higher level languages. These things make you a better programmer.
On the other hand, if you want to learn computer science you will have to disregard about the specifics. For instance, when it comes to see if an algorithm is more efficient than another, you shouldn't have the results be constraint by the particular CPU you have. Computer science is more akin to math, it is abstract.
Mainly shouldn't we avoid all abstractions and observe what really is happening at the very low-level?
No, you should not avoid abstractions. And yes, you can observe what happens at fairly low levels.
What time is it? Is it time to learn how stuff works or is it time to be productive?
If it is time to learn how stuff works, then don't avoid the abstractions... observe them in action from the lower level, you even create them yourself! Experience how and why they work the way they do.
If it is time to be productive, then don't avoid the abstractions...
Select the right ones for the task at hand and leverage them.
If you are at all interested in learning how to be more productive, consider that the tools are there to be used. Why would you try to pierce the wood pushing a nail with your bare hands when there are hammers available? Why would you use a magnetized needle and a steady hand to flip bits in a hard disk when there are text editors at hand?
Don't avoid the abstractions, they are tools.
I know why abstraction is great, but doesn't that prevent you from learning how computers work? Am I missing something?
You forget that you can learn multiple things. Learning Java doesn't prevent you from learning C, Learning C doesn't prevent you from learning C#. Learning OOP doesn't prevent you from learning data structures, learning data structures doesn’t prevent you from learning AOP. Learning assembly language doesn't prevent you from learning electronics; learning electronics doesn't prevent you from learning logic gates.
Nobody knows all that there is to make your computer works. But that doesn’t mean that you can reach a comfortable level of knowledge all across. Starting with nuclear physics, and all the way up to user experience, you can find courses online and communities with people willing to help.
Edit: the above one may be an unpopular opinion. I have three things to say about it: 1) I said comfortable - I mean, with yourself. I never said you will be a field expert. 2) I mention online courses as an starting point - and yes, there are online courses on nuclear physics (paid if you want something good, yet online). There are also courses that take you from logic gates to primitive video games 3) I understand that there is value in specialziation, and I didn't mean to encourage to learn all.
Yet again, consider if this is the best use of your time... when the client hires you to create a new mobile app, will you halt the project because you are yet to understand how semiconductors work? No, of course you don't.
The why is the detail. You may say "no" becase you are not interested in physics or materials... yet, you should say "no", because it is time to be productive. Regardless we agree that you can choose what abstraction levels you learn.
You may pretent you have been avoiding abstractions in general, you have only been avoiding some of them.
The approach of understanding everything by dividing it in its components falls short, it has fallen short in many disciplines. That is because there are emergent behaviors that are only visible - and thus can only be studied - when the components are integrated.
Do civil engineers bother by the position of individual atoms? no, they don't. They don't even bother to try to create new materials (that job is for a materials engineer) - for the civil engineer the materials are a convenient abstraction. They don't need to know how atoms are arranged, they need how much they cost and how they behave (how they react to stress, humidly, etc..), and nonetheless they know the materials are not magic.
There is little you can learn about biology if you insist in breaking everything into atoms. There is little you can learn about psychology if you insist in breaking everything into neurons.
You get the idea.