comp.lang.ada
 help / color / mirror / Atom feed
From: Karel Th�nissen <thoenissen@hello.nl>
Subject: Re: GOTO considered necessary (reworked)
Date: 1997/06/19
Date: 1997-06-19T00:00:00+00:00	[thread overview]
Message-ID: <33A8DB59.776F@hello.nl> (raw)
In-Reply-To: dewar.866548262@merv


Robert Dewar wrote:
> 
> John Volan said
> 
> <<If the structure were available in the language, of course there would
> 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:
> 
>    <<Sign>>
>       code to acquire sign
> 
>    <<Digits>>
>       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




  parent reply	other threads:[~1997-06-19  0:00 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-06-11  0:00 GOTO considered necessary (reworked) Samuel Mize
1997-06-11  0:00 ` Bryce Bardin
1997-06-12  0:00 ` Michael F Brenner
1997-06-17  0:00   ` Robert Dewar
1997-06-17  0:00     ` Robert A Duff
1997-06-20  0:00       ` Robert Dewar
1997-06-21  0:00         ` Robert A Duff
1997-06-21  0:00           ` Robert Dewar
1997-06-12  0:00 ` Anonymous
1997-06-12  0:00   ` John G. Volan
1997-06-16  0:00     ` Anonymous
1997-06-12  0:00   ` Robert Dewar
1997-06-12  0:00     ` John G. Volan
1997-06-13  0:00       ` Robert A Duff
1997-06-16  0:00         ` John G. Volan
1997-06-17  0:00           ` Robert Dewar
1997-06-17  0:00             ` Robert A Duff
1997-06-18  0:00               ` Spam Hater
1997-06-20  0:00               ` Robert Dewar
1997-06-20  0:00               ` Robert Dewar
1997-06-21  0:00                 ` Robert A Duff
1997-06-21  0:00                   ` Robert Dewar
1997-06-25  0:00               ` Wolfgang Gellerich
1997-06-25  0:00                 ` Samuel T. Harris
1997-06-25  0:00                 ` Michael F Brenner
1997-06-26  0:00                   ` Wolfgang Gellerich
1997-06-19  0:00             ` Karel Th�nissen [this message]
1997-06-19  0:00               ` Karel Th�nissen
1997-06-23  0:00               ` John G. Volan
1997-06-23  0:00                 ` Robert Dewar
1997-06-24  0:00                   ` Brian Rogoff
1997-06-25  0:00                   ` Featuritis not always bad (was re: GOTO considered necessary) Karel Th�nissen
1997-06-26  0:00                     ` Robert Dewar
1997-06-26  0:00                       ` Karel Th�nissen
1997-06-23  0:00                 ` GOTO considered necessary (reworked) Spam Hater
1997-06-25  0:00                 ` Karel Th�nissen
1997-06-23  0:00             ` John G. Volan
1997-06-17  0:00           ` Robert I. Eachus
1997-06-17  0:00           ` Robert A Duff
1997-06-25  0:00             ` Van Snyder
1997-07-21  0:00           ` Shmuel (Seymour J.) Metz
1997-06-13  0:00 ` Robert A Duff
1997-06-14  0:00   ` Samuel Mize
1997-06-14  0:00     ` Matthew Heaney
1997-06-14  0:00   ` Samuel Mize
1997-06-14  0:00   ` Robert Dewar
1997-06-16  0:00     ` Robert A Duff
1997-06-17  0:00       ` Spam Hater
1997-06-17  0:00         ` Robert A Duff
1997-06-19  0:00           ` Spam Hater
1997-06-17  0:00         ` Robert Dewar
1997-06-17  0:00           ` Spam Hater
1997-06-17  0:00           ` Robert A Duff
1997-06-19  0:00             ` John Herro
1997-06-25  0:00               ` Function result Van Snyder
1997-06-27  0:00                 ` Jon S Anthony
1997-06-27  0:00                 ` Robert Dewar
1997-06-20  0:00             ` GOTO considered necessary (reworked) Robert Dewar
1997-06-16  0:00     ` Spam Hater
1997-06-17  0:00       ` Robert Dewar
1997-06-17  0:00         ` Spam Hater
1997-06-16  0:00 ` Anonymous
1997-06-16  0:00   ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox