in reply to Re: A short, "iffy" rant
in thread A short, "iffy" rant

Ut oh, someone has decided to claim "if considered harmful".

If you're referring to my node "if" Considered Harmful in OO programming, I made it clear that this was a specific case of "if" statements being used inappropriately in a particular context. It was not a blanket condemnation of the "if" statement. I made that very clear in the node in question. I chose the hackneyed "considered harmful" title because I have a sense of humor, not a sense of dogmatism.

mapping ifs to hashes just makes hashes of virtual ifs...

I'm sorry, but I disagree. By using a dispatch table, one can frequently add another case to the table and it just works. It's frequently faster. It's a clearer specification of behavior. As your if/elsif/else construct grows, the dispatch solution becomes easier to read and maintain. As my first example shows, it's easy to get incorrect default behavior with if chains and sometimes you have to read through the chain to figure out where your particular statement belongs.

I would not argue that we shouldn't use "if" (my "friends don't let friends ..." comment was meant tongue in cheek.) Instead, I argue that we should take a close look at the logic involved with "if" statements and find ways to eliminate such logic, if feasible. It's far better to be able to create a behavior specification rather than potentially convoluted logic which hopefully covers all possibilities.

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re^3: A short, "iffy" rant
by SpanishInquisition (Pilgrim) on Oct 12, 2004 at 18:40 UTC
    Yep, I agree with that, and I was referring to it. "Considered harmful" should be "considered harmful". Tongue and cheek rarely works on the internet, hence confusion.

    As your if/elsif/else construct grows, the dispatch solution becomes easier to read and maintain

    No doubt about it.

    But what about

    if ($self->hungry()) { # go eat } elsif ($theater->open() && $self->wants_movie()) { # hunger is more important than movie } elsif ($cable->has_good_tv_show()) { # watch programming shows only, of course }

    Bad code, agreed ... but that doesn't translate into a dispatch table. I am quite the fan of dispatch tables.

    Dispatch tables work great for scalars if you are only testing scalars, usually your conditionals are more complex.

    I too, use the ternary operator most of the time (but never nested), as many things more complex imply too complex ... hence they can be redesigned ... but not always.

    Sometimes efficiency is important, and sometimes an if needs to be. Heck, sometimes if you pass through once a switch is what you want (but hey, perl doesn't have a good switch that is implemented without a source filter).

      if ($self->hungry()) { $self->go_eat(); return; } if ($theater->is_open() && $self->wants_movie()) { $self->go_watch_movie(); return; } ....

      If it is important that the maintainer notice that each choice is mutually exclusive, then make them extremely obviously mutually exclusive.

      Also, Ovid is discussing the fact that most if-statements are of a form that would be better written as a switch statement. Additionally, switch statements, in Perl, are nearly always better written as dispatch tables. And, if you really want a dispatch table, try the following:

      my @dispatch = ( [ sub { $_[0]->is_hungry }, sub { $_[0]->go_eat } ], ); foreach my $choice (@dispatch) { next unless $choice->[0]->( $self ); $choice->[1]->( $self ); last; }

      There's no rule that says dispatch tables have to be hashes of subrefs.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      A reply falls below the community's threshold of quality. You may see it by logging in.

      I think we definitely have the same opinion here. I could translate your code to a dispatch table by creating a method which creates a dispatch key, but I think it would be more trouble than it's worth. Your code is likely simpler.

      Cheers,
      Ovid

      New address of my CGI Course.