> 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 |
-- http://mail.python.org/mailman/listinfo/python-list