I will concern myself mostly with `goto`, but first a little on flow charts.
##On Flow charts
I see flow charts as just a ways to visually represent goto-ful low-level algorithms/code. Some other answers have mixed up their use with state-machines, or decision trees. Doing this could result in program-size complexity, for a sorting algorithm, of $O(n!)$ where the execution complexity could be only $O(n\log{n})$.
###Good uses of flow charts
The low-level nature of flowcharts can be of grate value, when creating a procedure to be carried out by humans. I.e. A first aid flowchart.
##On `goto` statement and goto
In the paper “Go To Statement Considered Harmful”, Dijkstra is concerned with the `goto` statement, not with goto. He points out that all higher order structures will use `goto` in their implement. According to Dijkstra, this implementation is not the problem, only the direct use of `goto`.
In the time since his paper the structure he mentions, `if`, `else`, `while`, `for`, `until`, `repeat`, sub-routines, have been part of our high-level languages. For his call was not for us to stop using it in programs, but to create languages that did not require it, and then to stop using it. And in the mean time to use it only in a structured way, to simulate the structures. Therefore only use it if your language does not provide the high-level structure that you need, and know which structure you are simulating (don't ad-hok it).
> For a number of years I have been familiar with the observation that the quality of programmers is a
decreasing function of the density of go to statements in the programs they produce. More recently I
discovered why the use of the go to statement has such disastrous effects, and I became convinced that
the go to statement should be abolished from all "higher level" programming languages (i.e. everything
except, perhaps, plain machine code). At that time I did not attach too much importance to this discovery; I
now submit my considerations for publication because in very recent discussions in which the subject
turned up, I have been urged to do so.
###Good uses of `goto` statement
- Programming is assembler, though you should not have much assembler language in your project.
- Compilers/generators: These will be using `goto` to create higher-level structures.
- To over come limitations of the language, but consider changing language: In `C` you may use `goto` to implement exception handling. However ensure that you have a clear idea of the structures that you are implementing. Do not use `goto` in an ad-hoc way.
###When `goto` can seem like a good idea.
`goto` is easy to understand, how it dose it. However the code that you create (beyond the most trivial) is not easy to understand what it does.
> My second remark is that our intellectual powers are rather geared to master static relations and that our
powers to visualize processes evolving in time are relatively poorly developed. For that reason we should
do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap between the
static program and the dynamic process, to make the correspondence between the program (spread out in
text space) and the process (spread out in time) as trivial as possible.
That is our attempts to understand a large system, in terms of how it works in a dynamic way, are going to be very limited. However it is possible to view the system in a static way, and thus make it easier for our brains to comprehend. To do this we must let go of a little of the how. We do not seem to have a problem with this in most cases: we care not how `print` is implemented.
###On assembler code and machines
So our CPUs use goto (`jmp` instructions). So what, unless you are teaching assembler language and CPUs.
But do all CPUs use goto? Possibly not, I am not an expert on this. However here is a discussion on what modern CPUs think of goto/jmp.
That happens when a modern (instruction pipelined cpu), fetches a conditional jump instruction?
All is not well, first it tries to guess which way the branch will go, then it goes that way. If it get it wrong it hits the breaks, backs up and tries again. The circuitry in the x86 for making this guess, is huge. The x86 does not like goto. What about the ARM, its branch prediction circuit is tiny (if it is a branch back, then assume that the branch will be taken, else assume that it will not), The ARM is better at predicting branches than the x86, but how? The arm has more conditional instructions, that is it has selection built in. This allows it to avoid goto a lot of the time. Its simplistic algorithm then assumes that a jump backward is a loop, and a jump forward is a selection. So though iteration is not explicitly encoded, and selection is only sometimes explicitly encoded. This shows that knowledge of the programs structure is not just a high level thing, it can help the CPU's performance.
##Conclusion
Only teach `goto`, when teaching assembler language, or at a late stage in high-level programming. However first teach the higher level structures, and make it clear that `goto` is only a work around for lack of higher-level structures in the language.