Velocity Reviews > Re: on goto

# Re: on goto

Seebs
Guest
Posts: n/a

 05-10-2010
On 2010-05-10, Richard Heathfield <(E-Mail Removed)> wrote:
> Actually, I think Seebs and I agree on a great deal. This happens to be
> something about which we mostly disagree, but even then we can find
> small but significant areas of agreement, if we look hard enough.

Yes.

> erroneously reconstruct it:
>
> found = 0;
> for(x = 0; !found && x < xlim; x++)
> {
> for(y = 0; !found && y < ylim; y++)
> {
> for(z = 0; !found && z < zlim; z++)
> {
> if(haystack[x][y][z] == needle)
> {
> point_assign(p, x, y, z);
> found = 1;
> }
> }
> }
> }
> return found;

> Laugh away, sirrah!

Okay, let's compare this with:

for (x = 0; x < xlim; ++x) {
for (y = 0; y < ylim; ++y) {
for (z = 0; z < zlim; ++z) {
if (haystack[x][y][z] == needle) {
point_assign(p, x, y, z);
return 1;
}
}
}
}
return 0;

I consider this much, much, easier to read. It gains even more if we
use the original's "return &haystack[x][y][z]".

In this case, I think yours is pretty close, because "!found && " is itself
a bit of an idiom. However, I find the latter easier to understand because
it's unambigously "loop over the entire array, doing { if you found a match,
set something and return 1 }", while for yours, I have to model it cognitively
as "loop until either something happens or we have covered this whole range,
doing { loop either until something happens or we have covered this whole
range, doing { loop either until something happens or we have covered this
whole range, doing { if you found a match, set something, and set something
else } } }".

Because the test conditions aren't part of the standard "loop over array"
idiom, I have to track both parts of the test condition separately, and doing
that for three layers of looping chews up six short-term memory slots, and
the index variables use up three more, leaving me solidly past my short-term
memory budget without even looking at the inner loop. For the form using
the pure idiom, I'm only using three slots -- I have x, y, and z as "the
current indexes in the loop".

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Phil Carmody
Guest
Posts: n/a

 05-11-2010
Seebs <(E-Mail Removed)> writes:
> On 2010-05-10, Richard Heathfield <(E-Mail Removed)> wrote:
>> for(x = 0; !found && x < xlim; x++)

> for (x = 0; x < xlim; ++x) {

> Because the test conditions aren't part of the standard "loop over array"
> idiom, I have to track both parts of the test condition separately, and doing
> that for three layers of looping chews up six short-term memory slots, and
> the index variables use up three more, leaving me solidly past my short-term
> memory budget without even looking at the inner loop. For the form using
> the pure idiom, I'm only using three slots -- I have x, y, and z as "the
> current indexes in the loop".

There's a 4th slot in use. It's
three trivial loops and one trivial special case
versus
three non-trivial loops

I agree that I view the former as simpler, (but am more likely
to be a break-user than a return-user).

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1

Phil Carmody
Guest
Posts: n/a

 05-11-2010
Richard Heathfield <(E-Mail Removed)> writes:
> Willem wrote:
>> Let's take your example to make my point:
>> Richard Heathfield wrote:
>> ) found = 0;
>> ) for(x = 0; !found && x < xlim; x++)

> No, the benefit of SESE is that you know that every loop has a single
> entry point and a single exit point.

It can exit after !found fails, or after x < xlim fails.

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1

Seebs
Guest
Posts: n/a

 05-11-2010
On 2010-05-11, Richard Heathfield <(E-Mail Removed)> wrote:
> Bait away. My preference for SESE is rooted in some truly appalling SEME
> code that I've had to maintain in the past.

Having read posts by Mr. Nilges, why do you persist in using English, when
it is clearly a language which supports apallingly bad writing?

Which is to say: The fact that bad code can be written which can be fairly
described as using multiple exits does not in any way establish that multiple
exits are at fault. It is quite possible to write deeply illucid code which
uses single exits. Multiple exits are not the underlying source of that
problem, any more than C is at fault for all the atrocious C out there.

C is very much a "here's the gun, here's your foot, do whatever you want"
language. Sometimes you need this. Similarly, multiple exits certainly
CAN create bad code... But sometimes that flexibility is needed to create
the best possible code for expressing something clearly and/or evaluating
it efficiently. Refusing to use them because someone somewhere used them
poorly is silly.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Seebs
Guest
Posts: n/a

 05-11-2010
On 2010-05-11, Phil Carmody <(E-Mail Removed)> wrote:
> Seebs <(E-Mail Removed)> writes:
>> Because the test conditions aren't part of the standard "loop over array"
>> idiom, I have to track both parts of the test condition separately, and doing
>> that for three layers of looping chews up six short-term memory slots, and
>> the index variables use up three more, leaving me solidly past my short-term
>> memory budget without even looking at the inner loop. For the form using
>> the pure idiom, I'm only using three slots -- I have x, y, and z as "the
>> current indexes in the loop".

> There's a 4th slot in use. It's
> three trivial loops and one trivial special case
> versus
> three non-trivial loops

> I agree that I view the former as simpler, (but am more likely
> to be a break-user than a return-user).

I was thinking about what I have to have in mind when I'm looking at the
contents of the inner loop. The trivial special case *is* the contents
of the inner loop -- it's no worse in complexity than the "found = 1" or
similar trait that some SESE advocates have proposed.

In the case of the "return a pointer to a[x][y][z]" function, I actually
rather liked using the pointer itself as the test-for-done, although I'm
not sure whether I should. In general, though, I've been using if (p) long
enough that a pointer is always comfortable for me as a boolean; either it
points or it doesn't.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Nick Keighley
Guest
Posts: n/a

 05-11-2010
On 10 May, 18:36, James Dow Allen <(E-Mail Removed)> wrote:
> On May 11, 12:03*am, Seebs <(E-Mail Removed)> wrote:
> > On 2010-05-10, Richard Heathfield <(E-Mail Removed)> wrote:
> > > Seebs wrote:

[seebs early exit]
[heathfield strict Single Exit]

> Well at least Heathfield and Seebs agree on *something*:
> We seek human cognitive advantage.
>
> The specific code being debated, IIRC, does *not* even involve
> goto's (*Please change the subject lines, people*), but is
> rather a trivial search through a 3-D array:
> * * *for ...
> * * * * *for ...
> * * * * * * *for ...
> * * * * * * * * *if ... return;
> In fact the code was so straightforward one might wonder why
> alternatives were even being proposed.

too right...

>*I did not search the
> thread rigorously; I noticed one code by Nathan(?) which
> seemed obviously inferior. *I gather C++ afficionados are
> proposing a new "access method" for such 3-D arrays (I find
> for...for...for much too easy to understand, especially since
> the full package will probably be doing this *many* places
> needfully, for an a priori unfamiliar method to be useful).
> Mr. Heathfield, IIRC, hasn't actually deigned to post an alternative.

I think he proposed

for (loop_incomplete OR not_found)
for (loop_incomplete OR not_found)
for (loop_incomplete OR not_found)
if ... found <- T

that is an extra boolean (and some extra testing)

> (Contrary to some beliefs I wrote my favorite goto in a smallish
> fraction of a day; to claim you don't have time to rewrite
> for for for if return ... well... *
>
> The thread title is "Goto" but break, inside return, and
> switch fallthrough suffer, to smaller extent, the same sin as
> goto. *

no, not really. Early exit isn't goto.

> On Apr 29, 3:20 pm, Tim Rentsch <(E-Mail Removed)> wrote:
> > Keith H Duggar <(E-Mail Removed)> writes:

>
> > > Subsequently I discussed that flame war with one of the worlds
> > > genius compiler writers who confirmed the necessity of the inlining
> > > etc controls explained above. However, he also added that in his
> > > experience it is pointless to argue with the anti-goto mob because
> > > it is a religion that ignores all inconvenient empirical evidence.

> > .
> > Essentially the same thing could be said of the pro-goto mob.

I rather be referred to as the Early Exit Mob

> Wrong. *The anti-goto mob claims to prefer code that
> is clearly more complex

well they don't accept your premise. Though I think abusing C's overly
complicated for-loop constuct is well on the road to ruin. {turing
over another rock and finding a can of worms]

> (is Nathan's the best you have?
> Did you ever post your solution, Mr. H?) in order to avoid the
> inside return (or goto). *None of us are "pro-goto" per se; we're
> just asking to *look at all the code and make the best trade-offs*,

I think everyone's claimign to be doing that. Unless someone wants to
pay the cognitive scientists to do their stuff we're stuck with "well,
MY way is OBVIOUSLY better" reiterated.

> or select the "least of evils." *It's usually better to introduce
> 1 or 2 boolean variables than to write goto,

or return or break?

> but what if it's 3
> variables and you still need a break? *What if by using switch
> case-fallthrough's you save the need for 5 little functions?

ah, sometimes the 5 little functions are good. Fowler "Refactoring"

> There is no "universal demerit system" for code complications,
> too aggressive.

yes. That's nearly a keeper

--
But ye have set at nought all my counsel, and would none of my
reproof:
I also will laugh at your calamity; I will mock when your fear
cometh;
[Proverbs 1:25]

Nick Keighley
Guest
Posts: n/a

 05-11-2010
On 11 May, 06:26, Richard Heathfield <(E-Mail Removed)> wrote:

> My preference for SESE is rooted in some truly appalling SEME
> code that I've had to maintain in the past.

but MEME is even *more* fun. But that needs a truly awesome assemly
programmer.

Nick Keighley
Guest
Posts: n/a

 05-11-2010
On 10 May, 19:05, Richard Heathfield <(E-Mail Removed)> wrote:
> James Dow Allen wrote:
>
> <snip>
>
> > Well at least Heathfield and Seebs agree on *something*:
> > We seek human cognitive advantage.

>
> Actually, I think Seebs and I agree on a great deal. This happens to be
> something about which we mostly disagree, but even then we can find
> small but significant areas of agreement, if we look hard enough.
>
> <snip>
>
> > Mr. Heathfield, IIRC, hasn't actually deigned to post an alternative.

>
> I'm reasonably sure I did deign to post an alternative. But I may not
> have done. I may merely have posted an alternative.
>
> To save me finding it, however, I'll very quickly and no doubt
> erroneously reconstruct it:
>
> found = 0;
> for(x = 0; !found && x < xlim; x++)
> {
> * *for(y = 0; !found && y < ylim; y++)
> * *{
> * * *for(z = 0; !found && z < zlim; z++)
> * * *{
> * * * *if(haystack[x][y][z] == needle)
> * * * *{
> * * * * *point_assign(p, x, y, z);
> * * * * *found = 1;
> * * * *}
> * * *}
> * *}}
>
> return found;
>
> Laugh away, sirrah!
>
> <snip>
>
> > Hope this helps,

>
> Yup. Style arguments are always fun.

both versions of the algorithm gave the same complexity measurement in
a tool I have. They both rated 5 for cyclometric complexity.

Nick Keighley
Guest
Posts: n/a

 05-11-2010
On 11 May, 09:29, Richard Heathfield <(E-Mail Removed)> wrote:
> Nick Keighley wrote:

> > both versions of the algorithm gave the same complexity measurement in
> > a tool I have. They both rated 5 for cyclometric complexity.

>
> McCabe, by any chance?

it just says "cyclometric". From the tool makers website:-

"Cyclomatic -- Cyclomatic complexity as per the original NIST paper on
the subject. Edges - Nodes + Connected Components."

> If so, how does the visual rep of the code come out? Which *looks* simpler?

the early exit version looks simpler on a graph (honestly!). But the
EE for-loops get graphed as single nodes whilst SE for-loops warrent
extra edges on the graph. I'm slightly surprised they gave the measure
considering the graphs look so different.

Nick Keighley
Guest
Posts: n/a

 05-11-2010
On 11 May, 10:07, Richard Heathfield <(E-Mail Removed)> wrote:
> Nick Keighley wrote:
> > On 11 May, 09:29, Richard Heathfield <(E-Mail Removed)> wrote:
> >> Nick Keighley wrote:

>
> >>> both versions of the algorithm gave the same complexity measurement in
> >>> a tool I have. They both rated 5 for cyclometric complexity.

>
> >> McCabe, by any chance?

>
> > it just says "cyclometric".

>
> I meant the tool maker's software.

ah, sorry I thought you were asking "which cyclometric complexity"

> If you're not using McCabe, I guess
> you're using "Understand"?

yup

> > From the tool makers website:-

>
> > "Cyclomatic -- Cyclomatic complexity as per the original NIST paper on
> > the subject. Edges - Nodes + Connected Components."

>
> >> If so, how does the visual rep of the code come out? Which *looks* simpler?

>
> > the early exit version looks simpler on a graph (honestly!).

>
> Any chance of a PNG (or BMP) of each? If you don't want to use your own
> Web space for this, you could perhaps email them to me, and I'll
> cheerfully find some scratch space for them.

webspace at present so I can email them. Is PDF ok or would you like
something else (I'll only alt-print screen them)