GOTO (was Re: Appeal for python developers)
Anthra Norell
anthra.norell at tiscalinet.ch
Sun Mar 6 08:26:12 EST 2005
> Please include "goto" command in future python realeses
> know that proffesional programers doesn't like to use it,
> but for me as newbie it's too hard to get used replacing it
> with "while", "def" or other commands
> --
I believe the bad reputation of 'goto' goes back to the originators of structured programming and what they meant to say was: don't use goto as a quick fix for a poorly written tangle of looping constructs. It aggravates the tangle when the solution is to straighten it out. Had they deemed 'goto' useless, they would have thrown it out there and then. They didn't, because a policy against misuse that prevents all use runs against the interests of those capable of avoiding the misuse on their own. Typically, elites revolt against dictatorial restrictions. Here, strangely, the elites afflict themselves voluntarily with a sort of gotophobia as a hallmark of professionalism.
I had a period when I was into state machines and came up with a programming technique that started out with a state table in three columns. This example is a vending machine.
Current state Transition event(s) Next state(s)
WAITING FOR ACTION customer drops coin COIN HAS BEEN DROPPED
customer selects beverage ORDER RECEIVED
customer cancels order ACCOUNT CLOSURE IS DUE
else WAITING FOR ACTION
COIN HAS BEEN DROPPED identify coin
credit account PAYMENT DUE IS UNKNOWN
ORDER RECEIVED display selection PAYMENT DUE IS UNKNOWN
PAYMENT DUE IS UNKNOWN no selection made NOTHING IS ORDERED
payment is short PAYMENT IS SHORT
else PAYMENT COVERS
NOTHING IS ORDERED prompt for selection WAITING FOR ACTION
PAYMENT IS SHORT display balance due
prompt for payment WAITING FOR ACTION
PAYMENT COVERS prompt for release action WAITING FOR RELEASE ACTION
WAITING FOR RELEASE ACTION customer activates release DELIVERY IS DUE
customer drops coin COIN HAS BEEN DROPPED
customer selects beverage ORDER_RECEIVED
customer cancels order ACCOUNT CLOSURE IS DUE
else WAITING FOR RELEASE ACTION
DELIVERY IS DUE release beverage
debit account ACCOUNT CLOSURE IS DUE
ACCOUNT CLOSURE IS DUE return account balance WAITING FOR ACTION
All of the next states reappear, no more than once each, in the first column as current states and so the table is consistent and exhaustive. Consistency is automatic regardless how big a table grows, if every new next state entered is copied right away into the first column where a bunch of them may accumulate, each one conspicuously unhandled as long as it stands alone on its line. Their order is irrelevant.
Converting the table into a program is trivial, because the table is a program. A few minor formal edits make it digestible for a C compiler:
WAITING_FOR_ACTION: if customer_drops_coin () goto COIN_HAS_BEEN_DROPPED;
if customer_selects_beverage () goto ORDER_RECEIVED;
if customer_cancels_order () goto ACCOUNT_CLOSURE_IS_DUE;
goto WAITING_FOR_ACTION;
COIN_HAS_BEEN_DROPPED: identify_coin ();
credit_account (); goto PAYMENT_DUE_IS_UNKNOWN;
ORDER_RECEIVED: display_selection (); goto PAYMENT_DUE_IS_UNKNOWN;
PAYMENT_DUE_IS_UNKNOWN: if no_selection_made () goto NOTHING_IS_ORDERED;
if payment_is_short () goto PAYMENT_IS_SHORT;
goto PAYMENT_COVERS;
NOTHING_IS_ORDERED: prompt_for_selection (); goto WAITING_FOR_ACTION;
PAYMENT_IS_SHORT: display_balance_due ();
prompt_for_balance_due (); goto WAITING_FOR_ACTION;
PAYMENT_COVERS: prompt_for_release_action (); // goto WAITING_FOR_RELEASE_ACTION;
WAITING_FOR_RELEASE_ACTION: if customer_activates_release () goto DELIVERY_IS_DUE;
if customer_drops_coin () goto COIN_HAS_BEEN_DROPPED;
if customer_selects_beverage () goto ORDER_RECEIVED;
if customer_cancels_order () goto ACCOUNT_CLOSURE_IS_DUE;
goto WAITING_FOR_RELEASE_ACTION;
DELIVERY_IS_DUE: release_beverage ();
debit_account (); // goto ACCOUNT_CLOSURE_IS_DUE;
ACCOUNT_CLOSURE_IS_DUE: return_account_balance (); goto WAITING_FOR_ACTION;
An anachronism? So what? Isn't it simple, elegant, legible, easy to modify and expand and self-documenting on top of it? One advantage of this method is that legibility does not degrade as the complexitiy of the transition paths increases. Conditional loops do become increasingly difficult to follow as they nest and accumulate breaks and state flags, and so modifications become increasingly difficult to make. An upgrade simpler than the following one, on the other hand, is hard to imagine:
COIN_HAS_BEEN_DROPPED: identify_coin ();
if coin_is_a_dud () goto HOLDING_UNWANTED_PROPERTY; // New
credit_account (); goto PAYMENT_DUE_IS_UNKNOWN;
HOLDING_UNWANTED_PROPERTY: reject_dud (); // New
/* admonish_customer (); */ goto WAITING_FOR_ACTION; // New
I used this technique in C and found it useful on some occasions. I did not combine gotos and loops. Not all problems lend themselves to this solution, But some do and that reminds that to judge merit it helps to ignore reputation.
Frederic
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20050306/b26894c3/attachment.html>
More information about the Python-list
mailing list