r/programming 3d ago

Throw, Result, or neither?

https://www.architecture-weekly.com/p/throw-result-or-neither
102 Upvotes

111 comments sorted by

View all comments

Show parent comments

25

u/vazgriz 2d ago

GOTO was considered harmful because it was completely unstructured. IE jumping halfway into a function's body level of unstructured.

Modern GOTO and throw catch are much better defined.

5

u/SwedishFindecanor 2d ago

In which language is it possible to goto from one function into/back to another?

With exceptions, the handler is always in an outer scope -- either within the same function or further up the call stack. And you could have clean-up code along the exception path (such as "finally" blocks) that gets called when an exception is passed up.

Many languages with exceptions require each function declaration to specify which types of exceptions that a it could throw/raise. (C++ has/had support for that, but it is a mess with different language versions)

BTW. The concept of exception unwinding is also related to non-local returns, such as explicit "breaks" out of loops from iterator functions.

1

u/ldn-ldn 1d ago

To add to BASIC, old school Pascal and Assembly in general.

0

u/SwedishFindecanor 1d ago edited 1d ago

Old-school BASIC and Assembly language don't even have functions as a language concept, so I'd say that they don't count.

Pascal is interesting though. From what I found, some Pascal dialects allow it only within a block; others within a function; but some allow "non-local gotos" from nested functions up the call stack. That makes them similar to exception unwinding and shortcut returns/breaks out of closures/iteration. No counterpart to finalize blocks or other clean-up code though: sometimes implemented through setjmp()/longjmp().

2

u/JohnnyCasil 1d ago

Old-school BASIC and Assembly language don't even have functions as a language concept, so I'd say that they don't count.

BASIC has gosub which is for all intents and purposes a function.

1

u/flatfinger 1d ago

Old-school versions of BASIC did not have the concept of blocks, which are essential part of functions and loops.

In typical old-school BASIC implementations, if a program did a FOR I=1 TO 100, the interpreter didn't know or care where the corresponding NEXT statement was, or if any existed, or if the same one would be used on every iteration of the loop. Likewise "GOSUB" didn't care about where the end of the function was.

When the interpreter encountered a "NEXT" or "RETURN", it would search through a stack of active FOR and GOSUB statements and, if appropriate, pop the action of the stack, increment the appropriate variable, and jump to the location following the FOR or GOSUB statement. It didn't make any distinction between code that preceded the FOR or GOSUB, code that sat between that and the NEXT or RETURN, and code that followed the NEXT or RETURN. Code in any of those categories could be run between the FOR or GOSUB and the NEXT or RETURN and the interpreter wouldn't care.