Teaching high-level versus low-level concepts
TL;DR Build a world, let the students program in that world.
This is largely a history lesson which, at the end, will give hints about how to teach students to become effective in a modern OOP language quickly.
A deeper principle than Higher to Lower abstraction, however, is the principle of teaching in a Spiral manner. This principle says that the student's education should not be linear, with each thing taught completely only once. Things should be reinforced repeatedly, with each turn of the spiral adding new concepts to old, but those new concepts themselves returned to later, each spiral reinforcing older lessons as well.
Another principle here is that students learn by doing, not by listening or reading. There are a few exceptions, of course, and teachers often fall into the exceptional class, but it is rare. I've written in answer to other questions here that learning involves physical, biological changes in the brain, requiring reinforcement. There is supporting research of course.
History
With that, let me take you back to about 1975 or so. The language Pascal existed then, but C did not. Pascal was not, at that time widely used in education. FORTRAN was. Early attempts to teach using Pascal resulted in &quot;poorly spelled FORTRAN&quot; programs, since that matched the thought processes of programmers and teachers well versed in FORTRAN. It is said that a new paradigm only takes hold after the people holding to the old one die out. This was actually the case with the Theory of Relativity in Physics. Einstein was dismissed (that &quot;clerk&quot;) by the superstars of the physics establishment until Poincaré's influence waned (and he died).
Pascal was created with the purpose of having a tool to directly implement Procedural Programming (PP). The essence of PP is this. Envision a Problem, P, as decomposed into a set of sub-problems, P1, P2, .... The sub problems have one of two characteristics. Either they can be immediately solved, Sk = solutionOf(Pk), or they can be, recursively, decomposed into yet smaller problems. Additionally it is assumed in PP, that there is a Known Composition method for putting the solutions to the smallest, undecomposed, problems together into a solution of the larger problem of which they are a part. In other words, decompose into sub problems going down and then recompose solutions going up.
Thus, a Pascal program was intended to look like a collection of simple procedures that invoked other simple procedures until you reach a state in which the lowest level procedures can be written in the primitives of the language. This was also called Top Down analysis and programming.
HOWEVER, early Pascal programs didn't look like that. There was a single massive procedure, or even just a BEGIN ... END. block that did everything, with only trivial parts factored out, usually those things that needed to be executed more than once. Hence, misspelled FORTRAN. Advice in early teaching materials was to factor out a procedure when it could be used several times, otherwise just inline the logic.
That was the state of affairs in about 1980. Then something magic happened. Richard (Rich) Pattis wrote a book called Karel the Robot (1981) that showed how it could be done. The book came with a simulation program in which students could write &quot;Karel Programs&quot;. The Robot Programming Language defined in the book and accepted by the simulator did not reveal primitive, machine level, constructs such as integer and real. There was a single robot that moved in a virtual grid-like world. There were five primitive actions: move (one block), turnleft (90 degrees), pickbeeper, putbeeper, and turnoff. Nothing else. beepers (a primitive kind of thing with no behavior) could be carried but there was no protocol for asking how many the robot carried. That was implicit in the program state, not something that could be queried. Beepers could also be found on the corners of the world. It was an error to try to pickbeeper with no beepers present.
In addition to the five primitives, the robot had a rudimentary sensing capability. It could sense a beeper on the same corner and it could sense a wall directly in front. Trying to move through a wall is a program error.
Notably, the robot programming language has no variables. Repeat: no variables. You can treat a corner, conceptually, as something like a variable since it can have several beepers and that can be treated something like an integer, but there is no protocol for converting it to an actual integer, and no way to build it.
With these tools, the programmer is able to write procedures (returning nothing) and predicates (returning booleans). There were no parameters of the procedures. Using the sensing capabilities, the student can utilize selection and looping to build sophisticated programs. Karel the Robot defined a Turing Complete language. More important, the book had a wonderful set of exercises. My contention is that if a student could solve every problem in the book they could, with their learned creativity, write any computer program (Turing Complete, remember). The book built programming skill, not just familiarity with machine concepts and language features.
The book has five chapters and in the original it was possible to cover it all in a bit over two weeks, at which point the path to Pascal was trivial. But at that point students could already produce a correctly structured PP program. No more misspelled FORTRAN.
The result is that students, in their first turn around the spiral, learn program structure with few low level details (five primitives, procedures, predicates, if, and while). The second edition of KtR by Pattis, Stehlik, and Roberts (1995) contains the first edition and adds specific hints on PP such as how to go about the problem decomposition and how to build IF and WHILE structures. But you can do anything. Sorting is fun, with beepers standing in as a kind of surrogate for integers, though you can't really count. Recursion is supported, though not discussed in the original. An interesting problem is to search an infinite space for a beeper.
Creativity Under Constraint
Another aspect of the teaching philosophy underlying this principle of Creativity Under Constraint. A naive view is that you can do more with more tools. However, learning to use a few tools to a very high level of skill builds mental structure that a fuller tool set will not. If a student depends on solving the next problem with the next tool, they will be a bit lost when there are no more tools available and you have to really think.  Creativity Under Constraint tries to avoid this.
As a simple example, consider poetry. If I ask you to write a poem you have few constraints. But that problem is hard hard. But if I ask you to write a Haiku, I give you constraints, but I also give you guidance and structure. The problem, though constrained, is actually easier (but not trivial, of course). This is a Big Idea.
It was vital that KtR provided this rigidly constrained world in which programming occurred, but not so rigidly constrained that any programming idea could not be expressed.
And of course, no one suggest you should only and always write Haiku.
Paradigm Shift
It is natural when a new paradigm arises (Relativity, Procedural Programming, OOP, Functional) for the practice to be thrown into a state of flux for a while, but hopefully not forever. The paradigm shift from a simpler form of imperative programming (FORTRAN) to PP was long and hard. Rich provided a tool that showed the way. It was widely adopted and helped teachers over the hump.
The interesting thing about a true paradigm shift is that it renders the earlier paradigm obsolete. A mounted knight in shining armor stood no chance of success against Henry V and his army of peasant longbowmen. And in turn they stood no chance against properly deployed musketeers. But deploying longbowmen the same way you deploy knights is just dumb.
In CS, however, a paradigm shift may not have such a profound effect, but over time, it will. Actually the last English king who was fully trained as a knight was Henry VIII and that was about 100 years after Henry V and the battle of Agincourt.
But, my way of thinking and teaching is to treat a (lesser) paradigm shift as if it were truly profound. Learn it. Adopt it. Teach it. Your students will be looking forward, of course, not back. And as I've said here before, my job isn't to teach them what I know, but what they need to know. Today that is a good solid view of OOP, for the most part.
And, programs no longer look like FORTRAN, but they, sadly, too often look like Pascal.
The Present State
We have gone through another Paradigm Shift, though it is now quite old, but too many people have not made the jump to OOP from PP. Too many programs are just PP programs with a few classes. Moreover, I see methods that are too long and too complex, putting the complexity into the methods themselves, rather than into interactions between objects viewed as bundles of behavior. Java, and later languages enable this, but using it effectively is an acquired habit (and taste).
The successors to KtR are Object Oriented. Karel J Robot (java), Karel R Tuesday (ruby), and Monty Karel (python), by Bergin, Stehlik, Roberts, and Pattis, all provide a structure, along with a simulation, in which good OO programs can be written using inheritance and composition, but with only a few ideas other than the essential ones. None of the books use integer primitives in any way. Variables are references to objects. These books are more complex than the original and require about half of a first course to cover. But at the end, the student has a clear grasp of the structure of an OOP program and can think about problem decomposition into a set of interacting objects. (These books permit the creation of several robots, not just one.) Once they deeply learn what is presented in the books it is a relatively easy task to introduce lower level concepts (int, array, ...) but also things like Collections and within reach. One drawback of the OOP Karel books is that inheritance is, perhaps, overemphasized, at the expense of composition of objects to build other objects. My personal view is that OOP enables composition primarily and inheritance secondarily, though the latter is more obvious in the syntax provided. Early on, however, Polymorphism is discussed deeply and implemented via composition using primarily the Strategy design pattern. Concurrency is also discussed briefly, since there are multiple robots.
Another feature/bug of the current books is that they use the actual languages (Java, Ruby, Python), rather than a constrained subset. While only a subset is taught, instructors are free to add things not in the books, such as integer valued variables and counting. This is a mistake, as the example below will demonstrate. One of the important (vital) choices of the designers what what NOT to teach or even include in the book. The Java book has a follow up, however, which fills in quite a lot for a full course.

Example:
To illustrate some of the above ideas and extend them a bit also, consider an exercise from Karel the Robot.
The robot, Karel, is at a corner facing East. Somewhere directly in front of the robot is a beeper (possibly even on the same corner). The Karel's task is to move to the beeper, pick it up, turnleft and move the same distance that was traveled to get to the beeper initially and put it down again.
Note: no variables, no integers, no counting is possible, except via recursion with the count held in the runtime stack, implicitly. And, of course, the previous sentence is an explicit hint.
The advantages of this are legion. You have a deep way to talk about recursion, especially the fact that recursion has two &quot;phases&quot;: winding - to get to the base case, and unwinding - to return all the calls. To do this exercise you need to do actual work in both phases, so you can talk about the fact that both are useful (and can introduce tail recursion which this example does NOT exhibit).
It is interesting in a way in which a standard recursive computation of, say, Fibonacci numbers is not.
It is an interesting problem because solving it changes the brain of the solver. However. If the student already knows how to count and has tools (int variables...) to solve it, this problem is completely boring and adds nothing (other than a bit of reinforcement) to changing the brain.
Moreover, later on, the instructor can return to this example (around the spiral) when counting is later taught and show how counting both simplifies it and makes it more dangerous, since such things as off by one errors are now more likely.
So, what seems simple, becomes profound because it is introduced into a constrained system. The constraints both give guidance/structure AND deepen learning in ways foreseen (we hope) by the designer.
Copacetic.

Notes: While Pascal set out to be the &quot;best&quot; language for  PP, it turned out to have flaws, especially for team based work. Modula-2 is much better, but is a true successor. However, it took lots of users writing lots of Pascal software to reveal the flaws. C++ started out as a better C+Simula. Object Pascal (from Apple) started out as a simpler Smalltalk, and Java is in that family, as are Python, Ruby, and Scala.