Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Re: block-based programming...

by flyingmoose (Priest)
on Apr 22, 2004 at 13:20 UTC ( [id://347341]=note: print w/replies, xml ) Need Help??


in reply to Re: block-based programming...
in thread block-based programming...

If you think about this being a state machine and you don't use CPAN code, you're (probably) reinventing the wheel. The standard distribution for handling state machines in Perl is POE*.
But it's big and clunky and doesn't read like normal Perl code. For a simple FSM, there is absolutely no reason to use POE, as POE tends to make your app into a "POE application", transmogrifing it. Reinventing your own will result in something a lot more concise. POE is cool, but it is *much* more than just a state machine, and I really doubt everytime someone recommends it that they have actually used it for that purpose. Implementation of basic state machines WITHOUT goto's is basic CS1, and those that use goto's to do this are doing really shoddy programming.

Gotos (and their P.C. cousins "abused exceptions") must die. They lead to poorly maintainable code that is both hard to read and trace.

A simple state machine without gotos (pardon the syntax errors):

$state = 'foo'; $running = 1; while($running) { if ($state eq 'foo') { # do stuff $nextstate = 'bar'; } elsif ($state eq 'bar') { # do stuff $nextstate = 'baz'; } elsif ($state eq 'baz') { # do stuff $running = 0; } $state = $nextstate; }

Replies are listed 'Best First'.
Re: block-based programming...
by Abigail-II (Bishop) on Apr 22, 2004 at 13:55 UTC
    Gotos (and their P.C. cousins "abused exceptions") must die. They lead to poorly maintainable code that is both hard to read and trace.
    There's no reason they lead to poorly maintainable code. They only lead to poorly maintainable code if they are misused. But it isn't too difficult to write spaghetti code using OO and no gotos - but that isn't a reason to say that OO must die. Perhaps you should read Knuth's paper "Structured programming with Go Tos", where he shows that if used appropriately, use of gotos is fine.

    Quoting from my own work, part of a C program I modified last week:

    __close1: if (close (soc) < 0) { if (errno == EINTR) { goto __close1; } perror ("close"); exit (1); }
    I don't think this is less maintainable than writing a loop.

    Abigail

      Gotos are almost as controversial as what constitutes good OO style. But they shouldn't be, since every construct that can be written with a goto can be written more clearly without one. I definitely agree both gotos and messy OO can obfuscate flow-control, so gotos are not the only evil. Here's how I would have done it:

      # keep trying to close socket until we succeed while (close(soc) < 0) { if (errno != EINTR) { # wasn't interrupted, this is some other failure, bail! perror("close"); exit 1; } }

      Your example is certaintly not less maintainble (yet), but this "block based" stuff above is an abomination when higher-level languages have more advanced constructs. That block based idea is fine for assembler or BASIC. Still, use of gotos encourages further use of gotos, and your particular use of goto and if's is logically a loop ... so just use the loop!

        ...every construct that can be written with a goto can be written more clearly without one.

        Try to rewrite TheDamian's Switch without the key goto $__; I dare you. Until you can do it, you haven't demonstrated that everything that can be written with a goto can be written without one (let alone written more clearly).

        More generally read the thread at (Ovid) Re: Re (tilly) 2: Paradigm Shift - Don't use strict to find out my opinion on when it is justified.

        The paper of Knuth's that was referred to there gives several other good reasons to use goto in at least some languages. Most of them boil down to the observation that there are many algorithms that can more efficiently be written with goto than without. At least in some languages.

        But not in Perl. A theorem that Knuth refers to from the literature is that any flow of control that can be achieved with goto can be achieved with nested loops and named loop control. Therefore in Perl you need extraordinary reasons to really need goto. (TheDamian had an example that I believe to be exactly that extraordinary.)

        Incidentally at Re: Re (tilly) 4: Paradigm Shift - when to use goto you will find a pre-processor macro from TheDamian showing you how to get named loops in C++. It uses goto, but considering that its purpose is to replace gotos that people write by hand with a more structured alternative, you may appreciate it.

        UPDATE: I just checked. It seems that TheDamian renamed $__ at some point. He now has labels named "C_A_S_E_$casecounter" instead.
        And you think that's more clear? For the sake of removing a goto, you introduce a while, which you, except for one specific case, aren't using as a while at all. Your condition suggests you'll keep trying until close() returns a non-negative value - however, what the code really is doing is retrying only if there's an interrupt. I strongly disagree that your while loop is more clear than a goto. Bending your code backwards to avoid using a goto isn't a good way of programming.

        Abigail

        And I would make a small change on that to use a break and reduce the level of indentation.
        while (close(soc) < 0) { if (errno == EINTR) continue; perror("close"); exit 1; }
        I hope that's valid C. I don't really use it much.
Re: Re: Re: block-based programming...
by Anomynous Monk (Scribe) on Apr 22, 2004 at 16:06 UTC
      ...but not his algorithms.

      As it wouldn't be wise to program all with plain sentences, Dijkstra's saying shouldn't be understood as a commandment.

      I see it as an algorithm to provide a good direction on everyone's programs.

      While I could do nearly everything programming in Basic, I could see the wisdom of thinking ahead a little and structuring the code before writting it. I personally saw it like growing up.

      {\('v')/}
      _`(___)' __________________________

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://347341]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-20 02:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found