[Israel.pm] Some thoughts about the "Red Flags" Presentation

sawyer x xsawyerx at gmail.com
Mon Dec 21 01:22:38 PST 2009


On Mon, Dec 21, 2009 at 1:48 AM, Shlomi Fish <shlomif at iglu.org.il> wrote:
>
> Hi all!

Hey!

> The first thing I've thought about was Sawyer's warning against using goto
> statements.
>[...]
> [...] some people have demonstrated that it is possible to do structured
> programming with goto statements, and sometimes even better with them than
> without them.

I've never denied the possibility of writing structured code using Gotos.
I do believe that well-crafted programmers are able to do so.

> In Perl I found little motivation to use goto so far, and usually did not have
> the need to in production code. But in non-C++ C (did not do a lot of C++ or
> ObjC) I found it to be a useful tool especially for the cleanup-on-failure
> pattern or to emulate Perl's "last LABEL" or "next LABEL".

This is precisely the point I was trying to make. Just because you
_can_ use Goto, doesn't mean you _should_.

When starting the lecture I pronounced that it relates to _very high
level_ languages and during the lecture I tried to stress that further
while saying that "in languages where you have extended workflow
operators, this would apply the most." I also said I understand the
need for it in C and C-like languages.

Unfortunately, some people still found the need to say "well, in C you
do not have "last LABEL" or "next LABEL", so I had to repeat what I
said.
I've had the same discussion with Ido when he expressed that "in some
languages you have to use Goto" and gave C as an example.

I have to say it was very disappointing to see that people completely
missed the point I was trying to make.

I started out as an Assembly programmer, so I know the "need" of
Gotos, trust me. However, (and this is the main point I'm making), in
very high level languages such as Ruby, Perl, Python and *shudder* PHP
(and the such), it can be quite the nuisance and is often used because
of C habits. This habit should stop. That is all.

> Sawyer later gave the argument that using goto was equivalent to using a jump
> in a conversation. However, when talking we use different conventions from
> when writing code, and we could say "do as I told you earlier" or "go to step
> 6" in conversation or writing. And what are the conversation equivalents of
> loops, subroutines, closures, coroutines/continuations, object inheritance,
> etc. and other thing we use in code? So it's not a right analogy.

I'm actually still rooting for this argument. I think that Perl has
expressed very easily how you can write code that "talks". Honestly, a
lot of the times, my readable code (and I work to create _very_
readable code) comes from trying to say what I want it to do and then
writing it. It doesn't cover everything but it covers a lot. For
example, I won't use "unless" or postfix if, because I (and apparently
a lot of others) don't natively look for these lines and can quite
often miss them. However, I do believe loops, subroutines and objects
can be easily (and are) expressed in conversations. Further more "go
to step 6" is instructions, not conversations, and it can often times
confuse the reader (case in point: construction instructions for
various furnitures which some fail to read), such as a goto in well
structured code in Ruby can confuse a programmer reading it.

I think I've said enough on this, so I'll reserve examples for blog
posts (I do have to write _something_ there :)

> Sawyer also gave a similar argument for criticising this construct which I
> tend to like:
> [...]
> (I'm flattered he read my code.)

I do believe I've also noted in the slides that you are allowed to do this. :)

> He claimed that putting an empty block was equivalent to a pause when saying
> "If the door is locked [pause]". However, it is equivalent to "If the door is
> locked do nothing - you're set", because we as humans don't interpret empty
> blocks, but can understand a "do nothing" imperative.

Actually no. What you're saying is "if the door is locked, do nothing.
otherwise, you have a problem and you need to alert your parents."
Notice that giving instructions in which we're actually blocking the
flow is... well, unnatural. It's something we do in conversations, but
out of fault and we usually try to correct this.

"You know how to reach my house? You know that tall building where all
the vegetables stands are? Yeah, the red one, exactly! That's not
where I live.... I live further down the road."
"Couldn't you just tell me that you live 'further down the road from
the tall red building where all the vegetables stands are?'"
"Well... uh.. I guess I could have."

Of course, in this conversation I tried to locate the person on the
vicinity, but programs don't have fuzzy memory, so it's not necessary.
If my friend didn't have fuzzy memory, saying "the big red building on
23rd street" would have been enough for him.

> Recently I've ran into the following code:
>
> <<<<
>
> my $var = ...;
>
> while ($line = ....)
> {
>        if (($var) = ($line =~ m{(...)}....
>        {
>                # Do nothing
>        }
>        else
>        {
>                die "Could not match var in line '$line'."
>        }
> }
> >>>>
>
> And I prefered to keep it this way because I was not sure of the !~
> implications. (Though now that I think of it, I could have used if (!(($var) =
>  ...).

This is a good reason to break that practice. If you're unsure of the
alternative, the "safer road" would be to take the path you _are_ sure
of.
Of course, I would kickstart re.pl (mst's Devel::REPL) and find out. :)
(then again, I always have a firefox on with a regex tester addon nearby)

> This is what I had to say.

I appreciate you took the time to say it.

Sawyer.


More information about the Perl mailing list