From: Ben Bacarisse on
James Kanze <james.kanze(a)gmail.com> writes:

> On May 2, 9:07 am, Juha Nieminen <nos...(a)thanks.invalid> wrote:
<snip>
>> Out of curiosity: Why have the requirement that one should
>> never exit from within a loop? Is there a rational reason to
>> enforce this requirement even in cases where exiting from
>> inside a loop would actually make the code simpler and easier
>> to understand (and possibly more efficient)?
>
> The argument is that such cases don't exist. I'll admit that
> I've never seen one. And there are really two separate
> arguments, which hasn't been made clear. One school of thought
> is that the loop conditions should express the loop invariants
> entirely, and be clearly stated up front, where anyone reading
> the code can easily see them. Another school of thought is more
> relaxed: it says, basically, that you can only have one exit
> from a loop, and allows the classical "loop and a half" idiom,
> where that sole exit is in the middle of the loop (and you have
> two sets of invariants, one empty, for the start of the loop,
> and one which isn't empty, for the end).

I think you may be using the wrong term here. For me, a loop invariant
is a condition that is quite separate from the loop's controlling
condition. It is true both before and after the loop (as well as being
true when the loop's control is tested) and is chosen so that combining
it with the negation of the loop's control gives the result we want to
assert about the loop.

For example, in a sorting loop one might choose the invariant:

I = A holds a permutation of the original data /\
A[0]..A[i-1] is sorted

If the loop's controlling condition, C, is i < N we can deduce that loop
termination implies !C /\ I which is enough to show what we need to show
about the result in A.

Having "internal" exit points will often have no effect on what makes a
useful invariant, and it often has no effect on the ease or difficulty
of proving it. What it may do it complicate the business of choosing
and proving the termination condition.

I think you have been talking about the terminating condition rather
than a loop invariant.

<snip>
--
Ben.
From: spinoza1111 on
On May 2, 3:58 pm, Juha Nieminen <nos...(a)thanks.invalid> wrote:
> In comp.lang.c++ Richard Heathfield <r...(a)see.sig.invalid> wrote:
>
>
>
>
>
> > Juha Nieminen wrote:
> >> In comp.lang.c++ Richard Heathfield <r...(a)see.sig.invalid> wrote:
> >>> If the data are sorted, bsearch.
>
> >>> If not, why not?
>
> >>> In any case, your loop condition expressions do not correctly describe
> >>> the conditions under which the loop will terminate. Please rewrite your
> >>> example so that they do, and then by all means ask me again if you wish.
>
> >>   No offense, but it always amuses me how some C programmers try to
> >> wiggle themselves out of actually giving honest answers when they are
> >> presented with problematic situations related to their coding style, C,
> >> or both.
>
> > Your paragraph, above, is a classic example.
>
>   You know, an answer of "no, you are" is rather childish. How about
> presenting some actual arguments instead?
>
>   I gave you a piece of code and asked you to modify it to conform to
> your principles. You did not do that. Who is trying to avoid answering
> to a challenge here?
>
> >>   And I have no idea what you mean by "your loop condition expressions do
> >> not correctly describe the conditions under which the loop will terminate".
>
> > That's the problem.
>
> >> Of course they do.
>
> > No, they don't.
>
>   Then why do you refuse to tell how the loops should have been written
> to conform to your specifications? I explicitly asked you to modify the
> code so that it would. Why are you refusing to do so?
>
> >> Is this just another attempt at wiggling yourself out
> >> of actually giving the answer?
>
> > No, it's an attempt at wiggling *your*self out of fixing your code.
>
>   Fixing my code? Oh, so there's a bug in it? Kindly point out what the
> bug is, please.
>
>   Or are you using the word "fixing" to mean "convert it to conform my
> views of how loops should be written"? If yes, then why are you asking
> *me* to do that? I don't know what *you* want the loops to look like.
> I'm *asking* you to explain it to me, with an actual example. Why are
> you refusing to do so? Why are you demanding me to guess wildly what is
> it that you want the code to look like?
>
>   Can you even answer that question? Why are you refusing to show me your
> way of writing those loops?
>
> >>   Is it *really* that hard to simply say "yes, in this particular example
> >> the 'return' is indeed the simplest way"? Does it hurt your pride or
> >> something?
>
> > What has pride got to do with it? It's common sense, that's all. The
> > simplest way (and one of the fastest) to get from Tower Bridge Approach
> > to St Katharine's Way is to jump off the bridge, but that doesn't
> > necessarily mean it's the /best/ way.
>
>   Then kindly show me this "best way".

Juha, this guy is afraid to make a positive response, because he
bullies people who make "mistakes" and he's afraid of eating his own
dog food.
From: Seebs on
On 2010-05-02, Richard Heathfield <rjh(a)see.sig.invalid> wrote:
>> I do not normally expect something structured like a three-dimensional
>> array to be sorted, I expect it to be a representation of objects.

> Then how on earth do you /find/ anything? It's O(N^3), for pity's sake!

Yup.

If you have, say, a representation of a three-dimensional object, where each
point holds information about a particular point in three-space, it is quite
possible that the most significant sorting is "sorted by location" rather
than "sorted by value".

> This is really an argument about programming philosophy. Juha seems to
> be in favour of the shortest code that does the job. I'm in favour of
> code that accurately describes what it's doing. while(i < j) is not an
> accurate description of the loop if you bomb out as soon as a[i] is 42.
> Why not just write while(i < j && a[i] != 42)?

Because, in some cases, the checks against a[i] make it harder to follow
the code.

I guess it's a question of how you do the translation.

for (i = 0; i < n; ++i)
if (long_funky_expression(a[i]) && more_stuff[i])
break;
if (i == n)
...

I don't see this as necessarily less clear than
for (i = 0; i < n && !(long_funky_expression(a[i]) && more_stuff[i]); ++i;
;

In general, in fact, I prefer the former. The loop is "iterate through
a". In this case, the idiomatic clarity of "we are looping from 0 to n-1"
is so much greater that "we are looping from 0 to n-1, and the operation
is to stop prematurely if..." is much clearer than "we are looping from 0
to either n-1 or the first value such that....".

A lot of it is just the strength of idiom when communicating. The reader
will be able to chunk the simple loops into single things rather than
complicated relationships, making it easier to read the code. My guess
is that, if you were to compare human responses to the two descriptions
above, you'd find that people were much more likely to correctly divine the
expected results of the first.

In short... It's like knowing that you can put a couple of case labels in
a row in C. Every user of C is aware that C provides for breaking out of
loops. A C programmer won't be surprised by it, and it is in fact the
canonical idiom for a large number of operations. Your style confuses the
user by conflating two unrelated tests. They really are unrelated; one is
expressing the range we're searching, the other is expressing what we're
searching for. Combining them into a single test obfuscates the loop,
even though it is possible to describe it as though it were simpler.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Seebs on
On 2010-05-02, James Kanze <james.kanze(a)gmail.com> wrote:
> It sounds to me almost the opposite. He's not really advocating
> a programming paradigm, as condemning one which definitely makes
> the code more difficult to understand.

Except he hasn't established that the other paradigm *definitely* makes
the code more difficult to understand.

And empirically, when someone converted a program using the condemned
paradigm, which everyone understood at first read, to one using his
preferred paradigm, several experienced programmers tripped over it,
because the resulting program was harder to understand. It's easier to
understand a simple rule with an exception than to understand a complicated
rule.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: James Kanze on
On May 2, 1:37 pm, Ben Bacarisse <ben.use...(a)bsb.me.uk> wrote:
> James Kanze <james.ka...(a)gmail.com> writes:
> > On May 2, 9:07 am, Juha Nieminen <nos...(a)thanks.invalid> wrote:
> <snip>

> I think you may be using the wrong term here. For me, a loop
> invariant is a condition that is quite separate from the
> loop's controlling condition.

Yes and no. As you correctly point out, there can be loop
invariants which aren't expressed by the controlling condition,
and they play an important role in evaluating the correctness of
the loop. It does, however, facilitate comprehension of the
loop if one of the invariants is that the loops termination
conditions haven't been met.

--
James Kanze