Abstractions are fine, but you have to be able to switch the abstractions level when necessary and understand the bits underneath, and I think it's natural to learn starting from low abstractions level and then building up. There are many basic low level issues that surface no matter how high level is the language you are using, I am not advocating teaching assembly to beginners, but a language like C and issues like:
- Direct addressing vs. indirect adressing, aka storing a value vs storing an address, aka pointers vs. values, aka call-by-value vs call-by-reference, ... Beginning programmers brought up on very high level languages are endlessly confused by the difference between copying the value and copying the reference.
- Understanding the stack and how procedure calls work. It might then be easier to understand why tail recursion in functional languages is cool but non-tail recursion not so much.
- Basic memory management. Why data structures are such a big deal.
...
All this shows why abstraction is necessary and useful in the first place, and what it's limitations are.