Posted by July 1, 2011
```Hi Steve,

On 7/1/2011 1:28 PM, steve wrote:

> ha, I deal with those "simplifiers" everyday, simplifying sometimes
> removes much insight and physical meaning to the algorithm your trying

It depends on *how* (and what) you are simplifying.  For example:

if ( (man)
|| (woman && pregnant) )

*clearly* is as easy to understand as

if ( man || pregnant )

If you look at a lot of conditionals, particularly, you can
see where the person writing it just didn't *think* about what
he was doing.  It's as if he laid out each individual possibility
"in a vacuum" without concern for the stanza of code immediately
preceding, etc.

Granted, some compilers can remove this redundancy.  But, it's
presence increases the chance of typographic errors creeping in
(e.g., "if (sex = MAN)" instead of "if (sex == MAN)" or
"if (sex != WOMAN)", instead) as well as adding a lot to clutter.
I *really* wish we had multicolored parens (no, not *colorized*
but actually inherently different "characters" -- like brace, bracket,
etc.) to make it easier to write and parse complex conditionals.
[which is why I resort to the style of the first example]

> to implement. A algorithm that natually has 8 logical steps to it
> should be left with those 8 steps, even if it can be reduced to 4
> cryptic steps and still give you the same answer. Because when that

Agreed.  Unless those steps are obvious in the resulting
code.  E.g., foo += 4 vs four instances of foo++;

> algorithm needs to be modified or debugged those 4 steps are going to
> have to unrolled into those 8 steps. I believe it's a carryover from
> the olden days when saving every byte of source code counted. C
> language itself is a perfect example of that mentality, trading too
> much simplification for readability.

I always found:
"Make everything as simple as it can be -- but no simpler"
an amusing axiom.  (on a par with "You always find the thing
you seek in the *last* place you look")
```
Posted by July 1, 2011
```On 01/07/2011 21:28, steve wrote:
> ha, I deal with those "simplifiers" everyday, simplifying sometimes
> removes much insight and physical meaning to the algorithm your trying
> to implement. A algorithm that natually has 8 logical steps to it
> should be left with those 8 steps, even if it can be reduced to 4
> cryptic steps and still give you the same answer. Because when that
> algorithm needs to be modified or debugged those 4 steps are going to
> have to unrolled into those 8 steps. I believe it's a carryover from
> the olden days when saving every byte of source code counted. C
> language itself is a perfect example of that mentality, trading too
> much simplification for readability.

I can only agree.

I'm not arguing for logic reduction for its own sake; if it hinders
readability, fergin fergit it.

However, I see code (regularly) that is *way* more complex than it needs
to be, simply because of a lack of factoring - there's loads of
duplicate code (and testing) because the coder is looking for conditions
within conditions within conditions, and then those same conditions
within conditions within *other* conditions, all of which could have
been reduced to a few *clearer* set of tests by way of e.g. a bit of
thought and a Karnaugh map...

Steve

--
http://www.fivetrees.com
```
Posted by July 1, 2011
```On Jun 28, 12:41=A0am, Arlet Ottens <usene...@c-scape.nl> wrote:
> On 06/28/2011 02:33 AM, Steve at fivetrees wrote:
>
>
>
>
>
> >> I use goto whenever it results in clearer and more readable code. Usin=
g
> >> "goto error" in a function that ends like this:
>
> >> error:
> >> cleanup_stuff();
> >> return retval;
> >> }
>
> >> is easy to understand. The 'error' label makes it clear what the purpo=
se
> >> is, even without reading any further, and it helps to keep the mainlin=
e
> >> code free of error handling. It may be possible to rewrite the code to
> >> avoid the 'goto', but if that doesn't result in any tangible benefits,
> >> why bother ?
>
> > There are any number of ways of avoiding this. One is to have an error
> > flag; set it if you need to do cleanup (not great). Another is to retur=
n
> > FALSE early if errors are encountered (see below; preferred).
>
> Except that 'return FALSE' doesn't work in the case above where you also
> need to call 'cleanup_stuff()' unless you duplicate the cleanup code,
> which is even uglier than error flags.
>
> >> I never worry about simplifying the logic, unless it helps readability=
.
>
> > Friend, I lost you right there. *Simplifying the logic can only help
> > readability*.
>
> Sometimes simplying the logic can help to increase readability,
> sometimes it doesn't. For the same reason, I sometimes write
>
> if( p )
>
> and at other times I write:
>
> if( p !=3D 0 )
>
> Sometimes I write: if( a && b ), and sometimes I write:
>
> if( a )
> =A0 =A0 if( b )
>
> It all depends on the circumstances, and "how it reads". It's not
> necessary the case that the simplest logic is the easiest to read,
> although usually it helps, and in that case I obviously simplify the logi=
c.

ha, I deal with those "simplifiers" everyday, simplifying sometimes
removes much insight and physical meaning to the algorithm your trying
to implement. A algorithm that natually has 8 logical steps to it
should be left with those 8 steps, even if it can be reduced to 4
cryptic steps and still give you the same answer. Because when that
algorithm needs to be modified or debugged those 4 steps are going to
have to unrolled into those 8 steps. I believe it's a carryover from
the olden days when saving every byte of source code counted. C
language itself is a perfect example of that mentality, trading too
much simplification for readability.
```
Posted by June 29, 2011
```On 6/28/2011 4:05 PM, Steve at fivetrees wrote:

> I should know better. I'm working with a chap (hi, Mike!) whose work I
> respect hugely. His code and my code will likely never approve of one
> another ;).

[fanfare]

*Core Wars*!!!
```
Posted by June 28, 2011
```On 6/28/2011 4:02 PM, Steve at fivetrees wrote:
> On 28/06/2011 05:17, Don Y wrote:
>> Of course, unlike your 88%RH, we're sitting at something like *seven* %.
>
> Ah.
>
> Where are you?

Arizona, USA.

> Steve
> (Will respond to rest of hugely interesting/challenging post when/if I
> get time.)

never mind that -- get back to WORK!!!  (slacker...)  :>
```
Posted by June 28, 2011
```On 28/06/2011 05:41, Arlet Ottens wrote:
>
>  > I suspect you're fairly new to this game (which I'm not)
>
> Yeah, I guess 25 years is fairly new.

Ah. Consider humble pie consumed ;).

I should know better. I'm working with a chap (hi, Mike!) whose work I
respect hugely. His code and my code will likely never approve of one
another ;).

Steve

--
http://www.fivetrees.com
```
Posted by June 28, 2011
```On 28/06/2011 05:17, Don Y wrote:
> Of course, unlike your 88%RH, we're sitting at something like *seven* %.

Ah.

Where are you?

Steve
(Will respond to rest of hugely interesting/challenging post when/if I
get time.)

--
http://www.fivetrees.com
```
Posted by June 28, 2011
```On 06/28/2011 02:33 AM, Steve at fivetrees wrote:

>> I use goto whenever it results in clearer and more readable code. Using
>> "goto error" in a function that ends like this:
>>
>> error:
>> cleanup_stuff();
>> return retval;
>> }
>>
>> is easy to understand. The 'error' label makes it clear what the purpose
>> is, even without reading any further, and it helps to keep the mainline
>> code free of error handling. It may be possible to rewrite the code to
>> avoid the 'goto', but if that doesn't result in any tangible benefits,
>> why bother ?
>
> There are any number of ways of avoiding this. One is to have an error
> flag; set it if you need to do cleanup (not great). Another is to return
> FALSE early if errors are encountered (see below; preferred).

Except that 'return FALSE' doesn't work in the case above where you also
need to call 'cleanup_stuff()' unless you duplicate the cleanup code,
which is even uglier than error flags.

>> I never worry about simplifying the logic, unless it helps readability.
>
> Friend, I lost you right there. *Simplifying the logic can only help
> readability*.

Sometimes simplying the logic can help to increase readability,
sometimes it doesn't. For the same reason, I sometimes write

if( p )

and at other times I write:

if( p != 0 )

Sometimes I write: if( a && b ), and sometimes I write:

if( a )
if( b )

It all depends on the circumstances, and "how it reads". It's not
necessary the case that the simplest logic is the easiest to read,
although usually it helps, and in that case I obviously simplify the logic.

> I suspect you're fairly new to this game (which I'm not)

Yeah, I guess 25 years is fairly new.

```
Posted by June 28, 2011
```Hi Steve,

On 6/27/2011 5:33 PM, Steve at fivetrees wrote:
> To expand my earlier vowel-heavy response:

(sigh)  I'd have rather watched Vanna twirl some consonants...

>>> The point here is that there are several places where "goto win"
>>> would have cleaned up the code. The do-while hack runs the
>>> risk of not being familiar to novices (and, also gives trouble
>>> if you want to "break break" -- requiring a flag and some
>>> kludge logic). And, the do-while cheats me out of three
>>> characters per line (because it introduces another indent level)
>>
>> I use goto whenever it results in clearer and more readable code. Using
>> "goto error" in a function that ends like this:
>>
>> error:
>> cleanup_stuff();
>> return retval;
>> }
>>
>> is easy to understand. The 'error' label makes it clear what the purpose
>> is, even without reading any further, and it helps to keep the mainline
>> code free of error handling. It may be possible to rewrite the code to
>> avoid the 'goto', but if that doesn't result in any tangible benefits,
>> why bother ?
>
> There are any number of ways of avoiding this. One is to have an error
> flag; set it if you need to do cleanup (not great).

Booo!  Then every conditional after that has to include "!error &&"
(assuming you *don't* want to execute the code protected by the
conditional if you've previously detected an error)

> Another is to return
> FALSE early if errors are encountered (see below; preferred).

But, if error means some form of *recovery* is required, that
means you have to wrap this portion of the code in a separate
function -- so that the caller can examine that error return
and unwind things, as appropriate.  If doing that requires
accessing something referenced *within* the called function
(the one that "error returned"), then you have to make that
data accessible to the calling function, etc.

> For me, using a goto is an admission of failure (to find a cleaner way),
> and I've not done this in 30+ years. There is *always* a better,
> cleaner, more comprehensible, and more robust way.

I don't think I would agree with that "unconditionally".
I figure Ritchie, et al are pretty smart folks and didn't
leave that feature in the language "casually".

OTOH, when they created Limbo, the noticeably *removed* the
"goto".

OTOOH, in creating Limbo, the gave "continue" and "break"
an optional argument -- an identifier indicating *which*
enclosing "loop" is being referenced (in effect, where
to "go to" as a result of the statement's execution).

[this must give the MISRA folks fits!  continue, break
*and* goto all cohorting together!!  :> ]

I don't think anyone is questioning the *need* for "goto".
But, rather, that ruling it out can make code clumsier
(e.g., the Limbo break/continue fits my style of wrapping
complex conditionals in do-while()'s and breaking, accordingly)

>> The extra indentation shouldn't be a problem, though. If you need more
>> than 3-4 levels of indentation, you should probably restructure the code
>> and/or use some extra functions anyway.
>
> I have a code-purity fascist at work ;). I love him dearly, as he's even
> more OCD than me. If I need a sanity check on something I'm doing, I run
> it past him. If he were to object to something I'm doing, it would make
> me think hard... but this hasn't happened yet.
>
> So... recently I ran something I do a lot past him. I had validation
> code that (simplified) looked like this:
>
> if ( ! first_bit_of_data_valid() )
> return( FALSE );
> if ( ! second_bit_of_data_valid() )
> return( FALSE );
> ... some processing...
> if ( ! processing_happy )
> return( FALSE );
> return( TRUE );
>
> These "early returns" get objected to (by n00bs, mainly) on the basis
> that some see them as glorified gotos; I don't. I see them as
> structurally sound, since they all wind up in the same place (a return).

This is equivalent to the example I posted.

The problem comes in when what you really want is:

if ( ! first_bit_of_data_valid() ) {
cleanup_mess_from_first_bit(params1);
return( FALSE );
}
if ( ! second_bit_of_data_valid() ) {
cleanup_mess_from_second_bit(params2);
cleanup_mess_from_first_bit(params1);
return( FALSE );
}

etc.

Sure, you can interpose another function to catch the "FALSE"
return value... but, that function needs to be able to access
all the stuff that the "cleanup" routines access -- potentially
in the context of the "false-returning function".

At some point, this just gets clumsy and forces you to
go out of your way *just* to avoid a goto.

> Consider for a second the indentation levels of multiple tests for
> validity without early returns - every time you do a test, you indent
> one more time. (I have worse examples: imagine maintaining time of day,
> then date.)

Exactly.  This is the case with the arbitrary precision decimal
arithmetic package I alluded to previously.  The code isn't
overly complex -- "tedious" is a better term (lots of care
to be sure you don't have fence-post errors, etc.).  Couple
that with my preference for informative (i.e., *long*) identifiers
and every level of indent starts to hurt.  Especially as it forces
same-line comments further and further out (making them shorter
and less effective -- hence my preference for comment blocks)

> So anyway, my OCD colleague thoroughly approved ;).
>
>>>> Similarly, I've seen a lot of code that is absolutely *infested* with
>>>> if/then/elses, where my background in hardware (Karnaugh maps, De
>>>> Morgan's theorem) has allowed me to simplify it to a few logical cases.
>>>
>>> <grin> I find I have to leave notes for folks explaining odd
>>> choices of conditionals. E.g.,
>>> if (! ((*ptr != 'e') && (*ptr != 'E')) ) {
>>> though that would be a bad choice, here.
>>
>> I never worry about simplifying the logic, unless it helps readability.
>
> Friend, I lost you right there. *Simplifying the logic can only help
> readability*. I suspect you're fairly new to this game (which I'm not)
> and have a few things yet to learn (as do we all). That's cool; don't be
> offended and try to keep an open mind about better ways. I've spent most
> of my career trying to find ways of keeping out of trouble (and being
> able to sleep nights) - that doesn't make my approach perfect (e.g. I
> avoid C++ at all costs, much to the scorn of my code-purity fascist
> colleague [I prefer good *design* over good *language*), but I do sleep
> nights [1].

I will often rewrite conditionals to exploit things that I
know to be true of the environment in which the code will
operate.  E.g., something that is more likely to affect
a conditional one way or the other might get "promoted"
to the front of the expression -- or, pulled into a separate
expression "enclosing" the other expression (to emphasize that
it is more significant to the algorithms performance).  It's
a minor efficiency hack but often can have rewards in loops,
etc.

> Steve
> [1] Except tonight. Too bloody hot. Am sitting by the aircon.

Pish!  30C?  It's *40*C at 9P, here.  High of 45C today.  And
tomorrow.  (and I plan on being outdoors much of tomorrow :< )

Of course, unlike your 88%RH, we're sitting at something like *seven* %.
```
Posted by June 27, 2011
```To expand my earlier vowel-heavy response:

On 25/06/2011 11:49, Arlet Ottens wrote:
> On 06/25/2011 10:39 AM, Don Y wrote:
>
>> The point here is that there are several places where "goto win"
>> would have cleaned up the code. The do-while hack runs the
>> risk of not being familiar to novices (and, also gives trouble
>> if you want to "break break" -- requiring a flag and some
>> kludge logic). And, the do-while cheats me out of three
>> characters per line (because it introduces another indent level)
>
> I use goto whenever it results in clearer and more readable code. Using
> "goto error" in a function that ends like this:
>
> error:
>      cleanup_stuff();
>      return retval;
> }
>
> is easy to understand. The 'error' label makes it clear what the purpose
> is, even without reading any further, and it helps to keep the mainline
> code free of error handling. It may be possible to rewrite the code to
> avoid the 'goto', but if that doesn't result in any tangible benefits,
> why bother ?

There are any number of ways of avoiding this. One is to have an error
flag; set it if you need to do cleanup (not great). Another is to return
FALSE early if errors are encountered (see below; preferred).

For me, using a goto is an admission of failure (to find a cleaner way),
and I've not done this in 30+ years. There is *always* a better,
cleaner, more comprehensible, and more robust way.

> The extra indentation shouldn't be a problem, though. If you need more
> than 3-4 levels of indentation, you should probably restructure the code
> and/or use some extra functions anyway.

I have a code-purity fascist at work ;). I love him dearly, as he's even
more OCD than me. If I need a sanity check on something I'm doing, I run
it past him. If he were to object to something I'm doing, it would make
me think hard... but this hasn't happened yet.

So... recently I ran something I do a lot past him. I had validation
code that (simplified) looked like this:

if ( ! first_bit_of_data_valid() )
return( FALSE );
if ( ! second_bit_of_data_valid() )
return( FALSE );
... some processing...
if ( ! processing_happy )
return( FALSE );
return( TRUE );

These "early returns" get objected to (by n00bs, mainly) on the basis
that some see them as glorified gotos; I don't. I see them as
structurally sound, since they all wind up in the same place (a return).

Consider for a second the indentation levels of multiple tests for
validity without early returns - every time you do a test, you indent
one more time. (I have worse examples: imagine maintaining time of day,
then date.)

So anyway, my OCD colleague thoroughly approved ;).

>>> Similarly, I've seen a lot of code that is absolutely *infested* with
>>> if/then/elses, where my background in hardware (Karnaugh maps, De
>>> Morgan's theorem) has allowed me to simplify it to a few logical cases.
>>
>> <grin> I find I have to leave notes for folks explaining odd
>> choices of conditionals. E.g.,
>> if (! ((*ptr != 'e') && (*ptr != 'E')) ) {
>> though that would be a bad choice, here.
>
> I never worry about simplifying the logic, unless it helps readability.

Friend, I lost you right there. *Simplifying the logic can only help
readability*. I suspect you're fairly new to this game (which I'm not)
and have a few things yet to learn (as do we all). That's cool; don't be
offended and try to keep an open mind about better ways. I've spent most
of my career trying to find ways of keeping out of trouble (and being
able to sleep nights) - that doesn't make my approach perfect (e.g. I
avoid C++ at all costs, much to the scorn of my code-purity fascist
colleague [I prefer good *design* over good *language*), but I do sleep
nights [1].

Steve
[1] Except tonight. Too bloody hot. Am sitting by the aircon.

--
http://www.fivetrees.com
```