From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,99222a5bd46ef3c9 X-Google-Attributes: gid103376,public From: Karel Th�nissen Subject: Re: GOTO considered necessary (reworked) Date: 1997/06/19 Message-ID: <33A8DB59.776F@hello.nl> X-Deja-AN: 251076469 References: <5nn2fm$11dk$1@prime.imagin.net> <199706121410.QAA05823@basement.replay.com> <33A0840B.1B41@sprintmail.com> <33A58C79.1C7A@sprintmail.com> Organization: Hello Technologies, Netherlands Newsgroups: comp.lang.ada Date: 1997-06-19T00:00:00+00:00 List-Id: Robert Dewar wrote: > > John Volan said > > < be no question of using gotos for the same purpose. Barring that, gotos > can be used to _simulate_ this structure, but this will always be a > dangerous practice, because the gotos are only at best a simulation of > the actual construct the programmer has in mind. Gotos lack > "robustness"; certain important properties of the hypothetical structure > (e.g., prevention of "fall-through" between states in an FSA) cannot be > guaranteed except by programmer vigilance. > >> > First, to me, the mapping of states into sections of code, and the mapping > of transitions as gotos, seems pretty direct -- direct enough that I do not > think it would make sense to dream up some syntactic gizmo -- although as > Robert Eachus points out, a preprocessor can very well provide the equivalent > of this syntactic gizmo. A gizmo like this: gizmo State : (one, two, three); -- the state variable is private to the gizmo (like loop indices) -- the state variable is read-only, but can change (like loop indices) initialStuff; transit one; state one; blaBlaTalk; transit ....; state two; smallTalk; -- use State as a read-only variable like a loop index transit ....; state three; fileBusterTalk; terminate; -- or something of that kind; needs more braincells spent end gizmo; > As for fall through, that is quite a bogus argument. If you map a FSM into > a loop/case structure with an explicit state variable, then you have to be > equally careful not to forget to modify the state variable. The error in one > case is accidental transition to the following state, the error in the other > is an infinite loop in one state -- not much to call there. Yeah, a bogus argument when compared with loop+case, not when compared with the dedicated gizmo. The gizmo should syntactically require that every state-block explicitly transits to the next state. The gizmo should trap ommions of transitions and unreachable states statically. Moreover, there is a clear distinction between transits/gotos that stay within the gizmo and the gotos that leave the gizmo all together. The gizmo can combine the efficiency (in its implementation) of the code+goto and the comfort of having a explicit state variable of the loop+case and add static safety. > Of course in practice, one of the advantages of the goto model is that in > some cases, it is quite natural to fall through to the following state: > > <> > code to acquire sign > > <> > code to acquire digit > .. > > if Another_Digit then > goto Digits; > else > goto Exponent; > end if; > > or somesuch, where Sign does fall through to Digits. I find this quite > readable [...] Right, but what happens during maintenance if the order of the states is altered or if new states are inserted or old states removed? This reminds me of the break in case-statements in C, with the same problems. Oh yes, it works, it hacks, but does this outweight the problems of ommisions in other cases, where execution accidentially falls through? For the compiler, there is no way to detect this error. Pretty un-Ada, I would say. The gizmo would require the safety of the explicit transit, but it might leave it out in the resulting code. Loop+case solutions have a similar problem of forgetting to indicate what the next state should be, so that the loop will repeat the same section of code over and over again. This can be fixed by invalidating the future state before the case statement and performing a check at the end: state := initialState; loop newState := invalidState; case state of when .... => ....; -- branches should assign newState when .... => ....; when others => raise someException; -- for missed states end case; if newState = invalidState then raise someOtherException else state := newState; end if; end loop; (It is possible to ommit the exception trapping at the end of the code and have the work done by the others-part of the case-statement, but then a useful diagnostic difference between forgetting the code for a state and forgetting to assign the new state is not reflected by the exception.) Look, what we have here: an auxilary variable, an additional state value, an additional branche, additional exceptions and additional processing. It works, errors are caught, but alas: at run time. > Basically an FSM of this kind *fundamentally* corresponds to spaghetti code, > in that the states are executed in some non-structured sequence depending on > the input, and therfore cannot be arranged into neat structures. True, therefore, one might do anything possible to avoid the programmers getting lost in spaghetti-space. Treat FSM's at their proper level so that errors are caught at compile time, so that maintenance is eased, and so that formal analysis of the FSM is a possibility. > As Robert Eachus notes, for a complex FSM, there is considerable merit in > using one of the standard tools to generate the code. True, but if we accept the added complexity of the tool and the necessary interfacing between the tool and the language and compiler, we might just as well extend the language with a special facility for processing FSM's. This will result in a clearer design of the software. A tool to generate the code for a FSM can be considered as an plug-in extension for the compiler, but regretfully with less knowledge of the rest of the code than a compiler would. As long as there is no syntactic gizmo for FSM's, we should do with code+goto or loop+case, I agree. As things are now, I do not object against the use of gotos in FSM's. The only (marginally?) substantial objection against the special gizmo is the extra number of reserved words that are necessary (e.g. *gizmo* 8-) , *state* and *transit*). Do not mention the added language complexity, because now, you either use a special tool of at least the same complexity (but less integration) or you use lower level approaches that are in practical life more complex and definitely less robust. Groeten, Karel