In mainstream programming education it is generally taught to "abstract as much as possible" because that's aligned with the capitalist way of technology -- high abstraction is easy to handle for incompetent programming monkeys, it helps preventing them from making damage by employing billions of safety mechanisms, it also perpetuates the cult of never stopping layering of the abstraction sandwich, creating bloat, bullshit jobs, it makes computers slower, constantly outdated and so drives software consumerism. This is extremely wrong. LRS advocates to employ only as little abstraction as needed, so as to support minimalism, i.e. too much abstraction is bad. For example a widely used general purpose programming language should basically only have as much abstraction as to allow portability, it should definitely NOT succumb high abstraction such as object obsessed programming.
In a more detailed view abstraction is not one-dimensional, we may abstract in different directions ("look at the issue from different angles"); for example functional, logic and object paradigms are different ways of abstracting from the low level, each one in different way. So the matter of abstracting is further complicated by trying to choose the right abstraction -- one kind of abstraction may work well for certain kinds of problems (i.e. solving these problems will become simple when applying this abstraction) but badly for other kinds of problems.
Let's take a look at a possible division of a computer to different levels of abstraction, from lowest to highest (keep in mind it's also possible to define the individual levels differently):
All content available under CC0 1.0 (public domain). Send comments and corrections to drummyfish at disroot dot org.