Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GOTOs not necessarily considered harmful?

189 views
Skip to first unread message

K.S. Bhaskar

unread,
Jan 14, 2021, 1:27:15 PM1/14/21
to
Why does C need a switch statement, when the same logic can be implemented with if…then…else? The reason is that the switch statement is more readable.

Virtually all programmers have heard of Dijkstra's admonition that GOTOs are considered harmful (https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf) and have been conditioned not to use GOTOs. I understand that undisciplined use of GOTOs leads to less understandable and hence less maintainable code.

But M GOTOs can implement an M flavor of the C switch statement (I expect the original M designers were inspired by Fortran's computed GOTO):

GOTO ONE:a=1,TWO:a=2,ELSE
ONE …
GOTO DONE
TWO …
GOTO DONE
ELSE …
DONE

Should such use of GOTO be tolerated / accepted / encouraged?

http://www.david.tribble.com/text/goto.html has an interesting and more extended discussion on the topic.

Regards
– Bhaskar

Roland Marquis

unread,
Jan 14, 2021, 8:18:08 PM1/14/21
to
On Thursday, January 14, 2021 at 7:27:15 PM UTC+1, K.S. Bhaskar wrote:

I prefer the DO M command:

DO ONE:a=1,TWO:a=2

Mark Dawson

unread,
Jan 14, 2021, 9:05:11 PM1/14/21
to
Bhaskar et al.,

This is an excellent question touching on readability and maintainability of code.

Before answering, I would like to observe that many developers seem to believe that all code is equally readable/maintainable, and matters of style matter very little. I could not disagree more strongly. I can read and make sense of any code I have had the occasion to work with, just as I can solve any Sudoku, however challenging. When solving a more challenging Sudoku, I probably experience a greater delight then when solving an easier one. With code, however, it is the opposite, as poorly written, less readable code takes longer to understand, is harder to maintain, and more risky to modify -- all of which costs my employer or my customer more resources to accomplish a given enhancement.

Between those who do value readability, there is room for debate. Some of it comes down to what one is familiar with, the style one is accustomed to reading.

To respond to the original question... I find post-conditionals to be less easily/quickly read than If statements. I would prefer thus:

IF a=1 GOTO ONE
IF a=2 GOTO TWO
GOTO ELSE
etc.

Better yet:
IF a=1 DO ONE
ELSE IF a=2 DO TWO
ELSE DO ELSE

Concerning GOTOs in general, they certainly have their place.

Best regards,
Mark

K.S. Bhaskar

unread,
Jan 14, 2021, 9:42:54 PM1/14/21
to
[KSB] That's not quite the same thing, as the DO will check for a=2 even if it did ONE because a was 1, and in the event ONE sets a to 2, that would cause a subtle bug.

Regards
– Bhaskar

ed de moel

unread,
Jan 15, 2021, 10:46:58 AM1/15/21
to
I know that many people don't like indirection, but the M[UMPS]y way of doing this would be:
in the initialization:
Set Goto(1)="ONE",Goto(2)="TWO"
and in the actual "switch":
Goto @$Get(Goto(a),"ELSE")

Given the ideas about GOTO, a
Do @$Get(Goto(a),"ELSE")
might be preferable.
(Of course, I'm assuming here that variable a would never have an empty value).

Rod Dorman

unread,
Jan 15, 2021, 2:24:42 PM1/15/21
to
In article <b02a86ba-f8bb-4eb7...@googlegroups.com>,
Mark Dawson <mark.r...@gmail.com> wrote:
> ...
>Better yet:
>IF a=1 DO ONE
>ELSE IF a=2 DO TWO
>ELSE DO ELSE

To defend against the subroutine not preserving $TEST one should write it as
IF a=1 DO ONE IF 1
ELSE IF a=2 DO TWO IF 1
--
-- Rod --
rodd(at)polylogics(dot)com

Mark Dawson

unread,
Jan 15, 2021, 8:55:12 PM1/15/21
to
My understanding is that the value of $TEST is preserved when invoking another procedure via a DO command (as well as an argumentless DO or function call) -- it's put onto the stack and comes off again when processing returns.

Is that not the case?

Mark Dawson

unread,
Jan 15, 2021, 9:00:42 PM1/15/21
to
(Snarky response -- I do not wish to offend, but... By "the M[UMPS]y way", do you mean clever but less easy to read?)

Serious response... Why would you characterize that as "the M[UMPS]y way"?

retired developer

unread,
Jan 16, 2021, 9:38:18 AM1/16/21
to
Hi,

the idea is nice, but (and this is my very private opinion) it has one
problem. It hides the context of the SWITCH statement. An example:

In C you have something like:

...
sel = computeYourSelector();
switch (sel) {
case 1: ...
case 2: ...
default: ...
}
...

One sees instantly, there are two cases and, if the individual blocks
are short, you see the whole case statement.

Your version is just one line:

...
set sel=$$computeYourSelector()
do @$get(Goto(sel),"ELSE")
...

I miss the context! Which are the possible selectors (i.e. the possible
values for *sel*? Even I don't know, where to look for a specific
selector block. The content of Goto(sel) could be any label in the
current routine or worse, in another routine.

You suggested, the selector-array should be set "in the initialization".
Merely, this could be in the current routine or somewhere else, far far
away from the "current switch statement, I'm struggling with".
Even worse, somewhere could be a dynamic change to your goto() array.
In the init you do:
set Goto(1)="ONE"
then later (possibly at a hidden place):
set Goto(1)="MYONE"
At least, I hope your selector-array will have a suitable name like
orderType() and not just a do() or goto().

On the other hand, with just one line of code, you can have a multilevel
CASE statemant, like

...
set s1=...
set s2=...
do @$g(myFlow(s1,s2,...,sN),$g(defFlow(s1,s2,...,s<N-1>,"genDEFAULT"))
...


There is one thing, I do not understand. In some kind, every
(programing) language is evolving except M (and except the ISC version).
Why? It seems, some people are proud to say, "I adhere to version
<put_in_here_youre_loved_version>" but nobody says, hey, give us
something new, for example a SWITCH command, block structures, TRY-CATCH
and many other things.


Regards,
Julius

--
An old Windows has old security holes.
A new Windows has new security holes.
Another OS has other security holes.
For safety you must care yourself.

K.S. Bhaskar

unread,
Jan 16, 2021, 10:50:44 AM1/16/21
to
The benefit of the switch statement and the M analog is single entry to a block of code at the top (the GOTO statement) and a single exit (the DONE label) at the bottom. If you use DO, you either have to add GOTOs to get to the end of the block, or you have blocks of code scattered around, and the reader loses the contextual locality. IMHO, the next best alternative is IF … ELSE IF … ELSE which loses a little readability, but has the single entry + single exit benefit.

Regards
– Bhaskar

retired developer

unread,
Jan 16, 2021, 5:15:55 PM1/16/21
to
On 16.01.21 16:50, K.S. Bhaskar wrote:
> The benefit of the switch statement and the M analog is single entry to a block of code at the top (the GOTO statement) and a single exit (the DONE label) at the bottom. If you use DO, you either have to add GOTOs to get to the end of the block, or you have blocks of code scattered around, and the reader loses the contextual locality. IMHO, the next best alternative is IF … ELSE IF … ELSE which loses a little readability, but has the single entry + single exit benefit.

I responded to Ed de Moel's suggestion (the M[UMPS]y way of doing this)
and to the consequences of the very same.

But yes, you can use IF/ELSE statements in M (and in other languages
too) to mimic C's SWITCH statement.

Merley, IF/ELSE isn't enough to fake a SWITCH, at least you need a
variable, where you put your selector:

The following works only, if <mySelector> is a variable. It could work,
if <mySelector> is an expression, especially, if the expression does not
have side effects (like $increment(), global access by naked syntax, etc.)!

if (mySelector = 1) ...
else if (mySelector = 2) ...
...

So it's a good idea to use a selectorVariable:

set selectorVar = <mySelector>
if selectorVar = 1 ...
else if selectorVar = 2 ...
...

Depending on each "CASE" body, you have to care about $TEST and to
handle large (CASE)bodies, either using argumentles DOs or block
structures (as ISC products have):

set sel=$$mySelector()
if (sel=1) do
. ;bodyline-1
. ;bodyline-2
else if (sel=2) do
. ;bodyline-1
. ;bodyline-2

I'm not a friend of argumentless DOs (they look ugly, years before, as I
worked on MSM systems, I often had "problems" after adding/removing DO
levels).

Interestingly, you doesn't said anything about further evolving of M.

K.S. Bhaskar

unread,
Jan 16, 2021, 6:21:56 PM1/16/21
to
[KSB] <…snip…>

> Interestingly, you doesn't said anything about further evolving of M.
> Regards,
> Julius

[KSB] <…snip…>

I am aware of no development of a next-generation M standard that is being carried out in the open with visibility to, and participation from, the programming public. I look forward to participating in the effort if and when that day comes to pass.

Meanwhile, my view is that programming languages are like religions – “I'll change mine if you change yours, but you go first.” It is important to separate M, the language, from M, the database. At YottaDB, our goal is to make the M database available to programmers in different languages, with the tight integration of the database to the language that makes the M language so capable. See https://docs.yottadb.com/MultiLangProgGuide/ to access an M database concurrently with applications written in C, Go, Perl, and Rust, in addition to M, with APIs being developed by the community for access from node.js, Python, and C++. So, even though M is my personal language of choice, I want to be inclusive rather than exclusive. I blogged about this a few years ago at https://yottadb.com/heritage-legacy-m-mumps-future-yottadb/

Regards
– Bhaskar

Maury Pepper

unread,
Jan 16, 2021, 8:59:13 PM1/16/21
to
On 1/15/2021 7:55 PM, Mark Dawson wrote:
<snip>
My understanding is that the value of $TEST is preserved when invoking another procedure via a DO command (as well as an argumentless DO or function call) -- it's put onto the stack and comes off again when processing returns.

Is that not the case?

Mark,
The answer is NO. True, $T is stacked with the argumentless DO, but to preserve backward compatibility with earlier standards, $T is not stacked when there is an argument. I always felt that $T should be stacked when there is an actuallist, but it is not. You can NEW $T in the called procedure. Not the clean approach I would like, but that's water under an old bridge.


winfrie...@e-ntwicklung.de

unread,
Jan 20, 2021, 12:14:45 PM1/20/21
to
K.S. Bhaskar schrieb am Donnerstag, 14. Januar 2021 um 19:27:15 UTC+1:
> Why does C need a switch statement, when the same logic can be implemented with if…then…else? The reason is that the switch statement is more readable.
>

Hello!

I totally disagree! The important reason for using switch-case in C is that (because the case-values must be constant integers and be known at compiletime) the switch-case-statement is much faster than nested / concatenated if-else-sequences.

switch-case has (in C) a constant time-behavior independent of
- the count of cases
- the nr of the concrete selected case.

In M this behavior can be simulated by

r in s lbl="T"_in
g:$TEXT(@lbl)'="" @lbl g Tdefault

T1 ;
w "This is case one",!
g END

T2 ;
T3 ;
w "This is case two and case three",!
g END

(Do you see an if? Or a post-condition? Only one, for the defaultcase! The rest can be done by compiler-optimization).
And the destination-labels have to be known at compiletime, they cannot be variables!
Another approuch would be to save the destinations in data, see the post of Ed de Moel.
(This makes a c-compiler internal in the produces assembler-code,
have a look here: https://stackoverflow.com/questions/3012011/switch-case-assembly-level-code).
What Dijkstra mentioned: Jumping crisscross through a programm will cause problems. The argumentless do with indented blocks in M
in conjunction with the stacked $TEST was an important feature in M. Historically M was designed as an unstructured language,
but with the nested block it made a transformation to a modern structured language.

George Timson

unread,
Jan 23, 2021, 4:08:03 PM1/23/21
to
Maury said: "...You can NEW $T..." on January 16.
No, that is not Standard.

--George

Maury Pepper

unread,
Jan 24, 2021, 3:55:19 PM1/24/21
to
Sorry, my oversight. I should have said that it is in the MDC draft standard but, in fact, is already implemented in some of the current versions in the field. Verify it works with your version before assuming it does.


Michail Sharymov

unread,
Jan 28, 2021, 3:20:32 AM1/28/21
to
понедельник, 25 января 2021 г. в 02:55:19 UTC+6, Maury Pepper:
The GOTO command is a tool. You can use it effectively or not. Do not know how, do not use. Dijkstra's didn't suggest banning GOTO, but be careful about using it.

Michail Sharymov

unread,
Jan 28, 2021, 3:20:54 AM1/28/21
to
понедельник, 25 января 2021 г. в 02:55:19 UTC+6, Maury Pepper:
I proposed a new language, MSH, which eliminates many of the problems of the M language. It does not require indirection, while maintaining the capabilities of this design. Introduced the CASE command, I believe that this command is necessary in the standard and better in Pascal notation, not C. Memory management with the New command is not flawless.
0 new messages