Flow charts, boolean logic, mathematics are fine modelling tools. However, they do not match a normal computer architecture. Therefore, language contructs primarily based on these models loose functionality which is easy in 'assembler'. Each extra model layer adds another set of possibilities where certain special cases just do not match their expected behavior, are far more complex than the could be, or just perform badly.
Programming errors happen, but most serious bugs have got something to do with ownership: out of bounds errors really indicate that the owner does not know where his ownership ends, dangling pointers or garbage are also a clear ownership problem.
Do not localy change the syntax rules because you can not express a concept otherwise, and do not overload symbols and identifiers: '<' means 'less-than', nothing else.
Every word should have meaning. Program code is not prose, you can not skip part of a sentence and assume you did not miss anything important. You have to read all and so you should not read a lot of filler words. On the other hand, words should have meaning. Forcing to much on one word or symbol means that you can not read; you are forced to decypher. When decyphering you are thinking about the meaning of a symbol/word, not about the meaning of a 'sentence' or program.
The principle of 'goto' is good, we use it all the time, we just call it 'if', 'while' etcetera. The problem is that goto hardly has any pragmatic meaning: it tell the program to go somewhere else, but it doesn't say why. Any symbol in a program language should have (if possible) a pragmatic meaning; usually if you can't specify the meaning of a piece of code, there is a bug or nasty depency lurking in there somewhere. Note that this makes all mathematical functions rather suspect.
Often languages have short notation for often used constructs. However, becasue of this short notation they fail to address the whole problem, and only solve the most common subset. This is not a bad idea per se, but there should be a generic language construct which solves all problems within the domain, and the shortcut should exist as exactly that: an often used limited solution.
Don't base a language paradigm on outdated compilation paradigms. In earlier days, compilers didn't have "nearly infinite" storage available to them, so minimal memory consumption was an important criterion in developing build tools. Nowadays we have more than enough resources to allow for much static analysis, but most language environments don't take advantage of that yet.
There is nothing wrong with garbage collection, like there is nothing wrong with calling stacks. Just not every problem is solved best by using garbage collection, as not every problem is solved best with calling stacks. Memory management should be under the programmers control.
Different things should look different, and equivalent things should look equivalent.