From: Balog Pal on

"Daniel T." <daniel_t(a)earthlink.net>
>> What do you mean by "dry spot principle"? I Googled it to find it
>> mentioned in only one book which I am not willing to pay for :D


don't repeat yourself
single point of truth

> I assume he is talking about:
> http://en.wikipedia.org/wiki/Don't_repeat_yourself


> Balog Pal and I have a different idea of what constitutes DRY in this
> case.

That should be weird...

> I think that having the extra variables creates two
> representations for the piece of knowledge in question

There are no extra 'variables' but constants.
> (tolower(a) and lo_a both represent the exact same thing.)

Huh? One is a transforming function and the other is a *result*. The piece
of code is supposed to work on that result.

> IMHO, his solution breaks DRY.

By *not* repeating the calls that is? Please explain in details how that
happens. And how you get to the single point of truth by pasting the
algorythm.

> I am pretty dogmatic about the single exit principle.

That would gain you another set of bad marks for in a good C++ shop. SESE
works fine for C, not as dogma but as a poor mitigation to lack of RAII.
In C++ you shall use RAII fr anything, and SESE is nothing but ilusion
anyway as you expect exceptions thrown in the code below the actual code
being 'transparent'.

And beyond an old dogma grown in a different context, SESE has no benefits
only the drawbacks. Read Alexandrescu for more details.

> I've had too many
> times when I was trying to find some hard to track bug in someone else's
> code only to learn that it had to do with some early return or continue
> that bypassed a critical piece of code.

And even more bugs can be found due to assignments (as the old saying goes,
"assignment is the same thing to the data flow as goto to the control
flow',
just data flow is much harder to follow and way easier to mess up...

And your SESE-looking thing can have (or gain without much notice!) an exit
in the middle -- if that makes the code break, it is no good.
And it is the natural thing to exit exactly at the point the function SHALL
not continue (being either done or hosed). As early or late as turns out.

> I'm not so worried about performance except in the later stages of a
> project. I'm more worried about reducing cyclomatic complexity. My
> function only has two possible paths, where the above has four.

Well, replacing tolower() with a homegrown inlined version is indeed
something we do only in embedded work...


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel T. on
"Balog Pal" <pasa(a)lib.hu> wrote:
> "Daniel T." <daniel_t(a)earthlink.net>
>
> > Balog Pal and I have a different idea of what constitutes DRY in
> > this case.
>
> That should be weird...

It should be weird that programmers disagree about how to write code? I
think not.

> > I think that having the extra variables creates two representations
> > for the piece of knowledge in question
>
> There are no extra 'variables' but constants.
>
> > (tolower(a) and lo_a both represent the exact same thing.)
>
> Huh? One is a transforming function and the other is a *result*. The
> piece of code is supposed to work on that result.
>
> > IMHO, his solution breaks DRY.
>
> By *not* repeating the calls that is? Please explain in details how
> that happens. And how you get to the single point of truth by pasting
> the algorythm.

I'm not pasting an algorithm, I'm calling a function to obtain a
property of a type, and calling a function more than once doesn't break
DRY.

The DRY code philosophy is stated as "Every piece of knowledge must
have a single, unambiguous, authoritative representation within a
system."

So which is the "single, unambiguous, authoritative representation" in
this case, tolower(a) or lo_a? Whichever answer you give, you are
breaking DRY by having the other hanging around. Storing the result in a
variable is a performance optimization, not a violation of DRY (IMHO a
premature and unnecessary performance optimization in this case.)

> > I am pretty dogmatic about the single exit principle.
>
> That would gain you another set of bad marks for in a good C++ shop.
> SESE works fine for C, not as dogma but as a poor mitigation to lack
> of RAII. In C++ you shall use RAII fr anything, and SESE is nothing
> but ilusion anyway as you expect exceptions thrown in the code below
> the actual code being 'transparent'.
>
> And beyond an old dogma grown in a different context, SESE has no
> benefits only the drawbacks. Read Alexandrescu for more details.

Single exit supports DRY. With only one return there is only one
(authoritative) place that the postcondition of the block of code must
be checked. I don't have multiple exits out of the middle of 'if'
statements or 'while' loops, why should I have them in the middle of
functions?

That said, many people have no problem with using break or continue to
jump out of the middle of a block of code and maybe you are one of them.
I consider it a style issue more than anything else. Some people have no
problem exiting blocks of code all over the place, I try not to.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Stuart Golodetz on
Daniel T. wrote:
> I had a job interview recently and I was asked to write three functions
> on a sheet of paper. I was given 45 minutes for this task.
>
> Function 1. Given a string of characters consisting only of upper and
> lower case letters, sort the characters in alphabetical order, lower
> case first (i.e., aAbBcC...)

I think others have largely answered the question you asked by now - but
this question did strike me as as good a time as any to use a nice
linear-time counting sort. Make a small array, accumulate the number of
times each letter appears, then output them in the right order. Things
like quicksort are overkill for this. As an added bonus, counting sort
is easier to implement too (if you're doing it from scratch, anyway).

Stu

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Balog Pal on
"Daniel T." <daniel_t(a)earthlink.net>
> "Balog Pal" <pasa(a)lib.hu> wrote:
>> "Daniel T." <daniel_t(a)earthlink.net>
>>
>> > Balog Pal and I have a different idea of what constitutes DRY in
>> > this case.
>>
>> That should be weird...
>
> It should be weird that programmers disagree about how to write code? I
> think not.

No, that is pretty common. ;-) (And before we switch context to the theory
field please note my first comment on the first example, that it is not a
big deal -- when the item is such small, there is much more leeway.)

But interpreting what "repeat" or "single" means should (IMO) not be
different. I.e if you state, that you like your solution better, and don't
care to apply DRY for this particular case, it is okay for me. But
stating it fits DRY, is not.

>> > I think that having the extra variables creates two representations
>> > for the piece of knowledge in question
>>
>> There are no extra 'variables' but constants.
>>
>> > (tolower(a) and lo_a both represent the exact same thing.)
>>
>> Huh? One is a transforming function and the other is a *result*. The
>> piece of code is supposed to work on that result.
>>
>> > IMHO, his solution breaks DRY.
>>
>> By *not* repeating the calls that is? Please explain in details how
>> that happens. And how you get to the single point of truth by pasting
>> the algorythm.
>
> I'm not pasting an algorithm, I'm calling a function to obtain a
> property of a type, and calling a function more than once doesn't break
> DRY.

tolower is IMO not a property and not of a type -- it is a mapping function.
The logic has two places to use th result of that conversion. Those places
are connected to each other, so should use the same thing instead of a
repeated call.

With so little code the difference may not be evident, but try to imagine
some evolution -- if some aspect changes in coding or requirements, how many
places need a change.

> The DRY code philosophy is stated as "Every piece of knowledge must
> have a single, unambiguous, authoritative representation within a
> system."
>
> So which is the "single, unambiguous, authoritative representation" in
> this case, tolower(a) or lo_a? Whichever answer you give, you are
> breaking DRY by having the other hanging around.

I don't get your reasoning. We have the original input character in 'a' and
nowhere else. We then have 'lower cased a' in lo_a. And nowhere else. (the
content of 'a' might be lowercase by some accident but that does not matter,
it is still a different thing.)

> Storing the result in a
> variable is a performance optimization, not a violation of DRY (IMHO a
> premature and unnecessary performance optimization in this case.)

tolower() being a pure and constexpr function seem to confusing the picture.
Imagine it is more abstract, and we needed to call some function in its
place, that may do unknown things in the implementation.

In that case, I guess, wanting to call it twice would not be so popular. And
most people would prefer my formulation.

>> > I am pretty dogmatic about the single exit principle.
>>
>> That would gain you another set of bad marks for in a good C++ shop.
>> SESE works fine for C, not as dogma but as a poor mitigation to lack
>> of RAII. In C++ you shall use RAII fr anything, and SESE is nothing
>> but ilusion anyway as you expect exceptions thrown in the code below
>> the actual code being 'transparent'.
>>
>> And beyond an old dogma grown in a different context, SESE has no
>> benefits only the drawbacks. Read Alexandrescu for more details.
>
> Single exit supports DRY.

Hm? Those are orthogonal things, better not mixed.

> With only one return there is only one
> (authoritative) place that the postcondition of the block of code must
> be checked.

As you can't check anything in the finction after the return it hardly has
any value -- and if you want to check the postcondition it can be done at a
caller site (as normally done in unit tests) that care nothing about the
number of exits.

Also, if you want to know the postcondition by just reading the code
(review), it is not at all easier with single exit for too many cases.
Especially if that postcondition have several cases by its nature. Please
take the time to look up AA's examples.

One classic example is search a thing in a collection. SEME solution
returns right where it is found and have another exit where not found. The
SESE version uses a framework of flags or other obfuscation measures. It
came up in countless many debates and I still waiting tor a reasonable
explanation how it that good. And especially easier to read or verify.

> I don't have multiple exits out of the middle of 'if'
> statements or 'while' loops, why should I have them in the middle of
> functions?

As I said the normal way is to exit right where you have reached the
postcondition not a mement earlier or later. It may be a single point, or
two or whatever many, and they can happen to be inside an if or while -- why
on earth not?

And if they are naturally there, making the execution continue, and smuggle
some results to a single point only increase the complexity and adds
opportunity to messing up instead of reducing it.

> That said, many people have no problem with using break or continue to
> jump out of the middle of a block of code and maybe you are one of them.

Of course. :) And I could add that I'm not afraid of using goto either if
(if!!!) that comes up as the best solution for the case -- just it is damn
rare in C++.

Believe me, being dogmatic is a bad thing. To go a little back to
originals -- If you were on my interview, a statement like you did, being
dogmatic SESE would map to an automatic "no hire" (after clarifying you
actually mean it). Because I stick to wizard rule #6 -- my only sovereign is
REASON. Dogmaitsm is the very opposite of reason. I expect programmers
to always be aware what they do, and be able to provide a rationale -- fit
for the particular case. Just as guidelines (any guidelines) are only as
good as they are understood -- and wielder can regress them to roots. (See
also "the five whys" from lean.)

> I consider it a style issue more than anything else. Some people have no
> problem exiting blocks of code all over the place, I try not to.

You skipped over the my mentioning exceptions. As exceptions can happen,
it is no longer just a style, and if one thinks some layout *has* the actual
SESE property just by restricting to a single return -- is quite mislead.
Thus imposing danger.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Stephen Howe on
>> I eschew strncpy because I can never remember if the terminating 0 is
>> included in the 'n' or not.
>
>Unfortunately, it is not. Which makes strncpy pretty useless.

Yes. I replace strncpy() code with the stylised

dest[0] = '\0';
strncat(dest, src, n);

which does terminate with 0 and does not unnecessarily pad dest with 0's if strlen(src) < n

Stephen Howe

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]