• GOTOs not necessarily considered harmful?

    From K.S. Bhaskar@21:1/5 to All on Thu Jan 14 10:27:13 2021
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Dawson@21:1/5 to All on Thu Jan 14 18:05:10 2021
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Roland Marquis@21:1/5 to All on Thu Jan 14 17:18:06 2021
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From K.S. Bhaskar@21:1/5 to Roland Marquis on Thu Jan 14 18:42:53 2021
    On Thursday, January 14, 2021 at 8:18:08 PM UTC-5, Roland Marquis wrote:
    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

    [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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ed de moel@21:1/5 to All on Fri Jan 15 07:46:57 2021
    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rod Dorman@21:1/5 to mark.r.dawson@gmail.com on Fri Jan 15 19:24:41 2021
    In article <b02a86ba-f8bb-4eb7-9de3-cfed0e9a6e0cn@googlegroups.com>,
    Mark Dawson <mark.r.dawson@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Dawson@21:1/5 to ed de moel on Fri Jan 15 18:00:41 2021
    On Friday, January 15, 2021 at 10:46:58 AM UTC-5, ed de moel wrote:
    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).

    (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"?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Dawson@21:1/5 to Rod Dorman on Fri Jan 15 17:55:10 2021
    On Friday, January 15, 2021 at 2:24:42 PM UTC-5, Rod Dorman wrote:
    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

    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From retired developer@21:1/5 to ed de moel on Sat Jan 16 15:38:14 2021
    On 15.01.21 16:46, ed de moel wrote:
    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).


    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From K.S. Bhaskar@21:1/5 to All on Sat Jan 16 07:50:42 2021
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From retired developer@21:1/5 to K.S. Bhaskar on Sat Jan 16 23:15:52 2021
    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.

    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From K.S. Bhaskar@21:1/5 to All on Sat Jan 16 15:21:55 2021
    [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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Maury Pepper@21:1/5 to Mark Dawson on Sat Jan 16 19:59:10 2021
    This is a multi-part message in MIME format.
    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.
    **


    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <div class="moz-cite-prefix">On 1/15/2021 7:55 PM, Mark Dawson
    wrote:<br>
    </div>
    <blockquote type="cite"
    cite="mid:b79c625d-708d-4ba6-8915-3b2f75671931n@googlegroups.com">&lt;snip&gt;
    <pre class="moz-quote-pre" wrap="">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?
    </pre>
    </blockquote>
    <br>
    Mark,<br>
    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.<br>
    <font size="+1"><b></b></font><br>
    <br>
    </body>
    </html>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From winfried.bantel@e-ntwicklung.de@21:1/5 to K.S. Bhaskar on Wed Jan 20 09:14:43 2021
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From George Timson@21:1/5 to All on Sat Jan 23 13:08:02 2021
    Maury said: "...You can NEW $T..." on January 16.
    No, that is not Standard.

    --George

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Maury Pepper@21:1/5 to George Timson on Sun Jan 24 14:55:17 2021
    This is a multi-part message in MIME format.
    On 1/23/2021 3:08 PM, George Timson wrote:
    Maury said: "...You can NEW $T..." on January 16.
    No, that is not Standard.

    --George

    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.



    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <div class="moz-cite-prefix">On 1/23/2021 3:08 PM, George Timson
    wrote:<br>
    </div>
    <blockquote type="cite"
    cite="mid:351042ed-9f8d-4433-9988-528138d761a3n@googlegroups.com">
    <pre class="moz-quote-pre" wrap="">Maury said: "...You can NEW $T..." on January 16.
    No, that is not Standard.

    --George
    </pre>
    </blockquote>
    <br>
    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.<br>
    <br>
    <br>
    </body>
    </html>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michail Sharymov@21:1/5 to All on Thu Jan 28 00:20:53 2021
    понедельник, 25 января 2021 г. в 02:55:19 UTC+6, Maury Pepper:
    On 1/23/2021 3:08 PM, George Timson wrote:
    Maury said: "...You can NEW $T..." on January 16.
    No, that is not Standard.

    --George
    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.
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)