On Tue, Dec 1, 2020 at 3:40 PM Bakul Shah <bakul(a)iitbombay.org> wrote:
On Dec 1, 2020, at 12:20 PM, Steffen Nurpmeso
<steffen(a)sdaoden.eu> wrote:
Never without my goto:, and if it is only to
break to error
handling and/or staged destruction of local variables after
initialization failures. Traumatic school impression, finding
yourself locked in some PASCAL if condition, and no way to go to.
Pascal had goto.
Pascal also had to go. (Thanks...I'm here all week.)
You can even do a non-local goto!
In Go you don't need goto for the sort of thing you and McVoy
talked about due to its defer statement and GC. Now granted
GC may be too big of a hammer for C/C++ but a future C/C++
add defer gainfully as the defer pattern is pretty common.
For example, mutex lock and unlock.
C++ has had something analogous for some time: destructors that run when an
object goes out of scope. Scope guards to do things like close files and
auto-release locks on exiting a critical section are pretty common in that
world, and in general, preferable to many of the alternatives (either
deeply nested conditionals or banks of labels and `goto fail1;` `goto
fail2;` etc, that successively release resources on return; the latter is
basically hand-rolling what the language does automatically for you, and
has been the cause of at least security-related bug: apple's "goto fail"
bug in their SSL implementation).
There's still no easy way to break out of nested loops, though.
But I have mixed feelings about goto vs continue/break. A nested
loop with multiple continue/break can be as obscure.
I submit that it's in how you write it: if the set of conditions on which
one would break/continue are explicit and early in the loop body, it can be
a very expressive way to write something. But like any tool, it can be
abused.
Along those lines, it's always been interesting to me the way that
Dijkstra's statement about goto must have influenced language design. The
original "GOTO Statement Considered Harmful" note was quite damning, but I
wonder if it meant to be: it strikes me that the really dangerous thing
about "goto" isn't its mere existence or even its use, but rather,
it's
unconstrained use when better alternatives exist in the language. As one
can observe in well-written C code, judicious use of `goto` can be quite
elegant in comparison to the alternative.
I've often wondered whether language designers, mindful of the pitfalls of
`goto`, eventually took the most useful patterns of its usage and extracted
them to stand on their own. Early returns from functions are an obvious
example, but so are `break` and `continue` and one might argue exceptions
fall into the same category. It strikes me that as we gain ever greater
experience with languages, we find more and more examples of things one
routinely does using a blunt instrument like goto, and we refine those to
first-class features of the language.
I think it's also illustrative of how social pressure can influence one to
avoid "dangerous" patterns in favor of these language features. C isn't
inherently more dangerous because it has a goto statement and labels; most
of the time, one doesn't bother to use goto because alternatives exist that
are more natural and fill the same role (continue, break, return, etc).
- Dan C.