Yes, indirection in the source "abstraction" is the way to get to a new abstraction.
However, the result has to be an actual abstraction for that to work, and it often isn't. Often it's just indirection. And once you have the new abstraction, you have to be able to express yourself using that abstraction with little or no leakage.
For example, the "procedure" abstraction works that way, we really and truly don't have to care how it is constructed from assembly language instructions roughly 99.999% of the time.
But here's the kicker: since the actual abstraction mechanism in our languages is procedural, we can only create essentially procedural abstractions. For all other kinds of abstractions, the leakage is close to 100% and we are left with just indirection.
In the code.
Which means we need to take our abstractions and hand-compile them to fit our procedural languages, which we do with varying degrees of deftness. And then mechanisms of communicating the actual but mostly implicit "source" program become crucial, as you point out.
I'd rather be able to create and express those abstractions in the code itself. And then be able to program with those abstractions, rather than having to program in the target language of the human compiler.
> But here's the kicker: since the actual abstraction mechanism in our languages is procedural, we can only create essentially procedural abstractions. For all other kinds of abstractions, the leakage is close to 100% and we are left with just indirection.
Not quite true. "Abstraction" is what you imagine/design according to your needs and treat as a "Single Concept" (eg. a Design Pattern). The fact that it is made out of more granular elements i.e. machine instructions/language statements/procedures for a state machine does not change your ability to reason and work with abstractions at a higher level. While there maybe some "leakage" (mainly when things fail/need for performance) it is by no means total.
Also many people often equate Abstraction with Indirection since the latter is so prevalent in defining the former. But they are different concepts and have to be treated as such.
Yes, indirection in the source "abstraction" is the way to get to a new abstraction.
However, the result has to be an actual abstraction for that to work, and it often isn't. Often it's just indirection. And once you have the new abstraction, you have to be able to express yourself using that abstraction with little or no leakage.
For example, the "procedure" abstraction works that way, we really and truly don't have to care how it is constructed from assembly language instructions roughly 99.999% of the time.
But here's the kicker: since the actual abstraction mechanism in our languages is procedural, we can only create essentially procedural abstractions. For all other kinds of abstractions, the leakage is close to 100% and we are left with just indirection.
In the code.
Which means we need to take our abstractions and hand-compile them to fit our procedural languages, which we do with varying degrees of deftness. And then mechanisms of communicating the actual but mostly implicit "source" program become crucial, as you point out.
I'd rather be able to create and express those abstractions in the code itself. And then be able to program with those abstractions, rather than having to program in the target language of the human compiler.