Re: Letter to US Sen. Byron Dorgan re unpaid overtime

From: Richard Heathfield (dontmail_at_address.co.uk.invalid)
Date: 12/22/03


Date: Mon, 22 Dec 2003 00:52:23 +0000 (UTC)


[snippage fairly random, and for once, I haven't bothered indicating it.
I've retained relevant material where necessary, as usual. Sorry about the
500+ lines. Eek.]

Edward G. Nilges wrote:

> Richard Heathfield <dontmail@address.co.uk.invalid> wrote in message
> news:<bs3sn1$hv1$1@sparta.btinternet.com>...

>> I make no claims to being a VB.NET programmer. Of course,
>> if VB.NET were standardised, I could have looked the answer up in the
>> Standard. But it isn't, so I couldn't.
>
> You'll notice no campaign of libel based on your not being a VB.Net
> programmer. Nonetheless, when I resumed, in response to a request
> (made I now know in bad faith) by Chris Sonnack, with C code,
> confessing at the time to having abandoned C, I was subject to a
> campaign of libel.

No, that's just a lie or a very silly (and repeatedly made) mistake. Nobody
libelled you. Any damage done to your reputation was entirely of your own
making.

> I suggest in future you emulate my conduct which is
> truer than yours to the ethics of posting. Thank you.

<hollow laugh> Since I know for a fact that you have lied in this very
newsgroup, and since it is obvious to all that you ignore the topic of the
group and swear at some of those who point this out, I am not in the
slightest bit interested in emulating your behaviour.

>> If you want Fortran or Basic, you know where to find them.
>
> No, I want Algol. I shall have to develop a Windows compiler myself it
> appears (Fujitsu may have one).

Then you know where to find Algol. Whatever.

>> If you don't like C, don't use it. But
>> to try to impose your likes and dislikes on others is an exercise doomed
>> to failure.
>>
> It appears to me that this is what you do, the only difference happen
> to be that your opinions coincide with those of the tribe.

Well, I'm a great believer in personal choice. I don't believe in imposing
/any/ language on /anyone/. C happens to be /my/ language of choice. That
doesn't mean it's right for everybody.

>> > It means that the C programmer has to think in Fortran terms to write
>> > clear code.
>>
>> No, it means that the C programmer had jolly well better be able to think
>> in C terms to write clear code.
>>
> I find the use of "clear" disturbing since it is NEVER qualified with
> respect to a reader response.

It was *you* who introduced the word. Duh. Don't you read what you write?

>> I often invoke the terminating condition of a for loop manually inside
>> the loop, and do not find it even remotely unsafe. Example follows (E&OE
>> - this is hand-typed, not an extract from an actual program):
>>
>> for(thisline = 0; SUCCESS == rc && thisline < numlines; ++thisline)
>> {
>> rc = ProcessLine(line[thisline]);
>> }
>>
> This is not a for loop in the Fortran sense

No, it's a for loop in the C sense. Well spotted. Give the man a five-cent
cigar (and charge him five cents). [Hint: I intended it to be a for loop in
the C sense. That's why it's a for loop in the C sense.]

> and it shows the kind of
> sloppy thinking that results from confusing a programming language
> with programming.

No, it shows a for-loop.

> Also, this is an ugly piece of code. It increments the line counter
> unnecessarily since rc is set to a value, then thisline is incremented
> (for some strange reason, in a nonstandard fashion, in a
> preincrement), then the condition is evaluated.

The line count increment is necessary because the value is used as an offset
into the array. The preincrement is not non-standard at all. The Standard
defines the behaviour perfectly. The condition is evaluated before each
loop iteration, not after. You really don't understand this language at
all, do you?

> Following the code thisline points EITHER one past the bad line or one
> past the number of lines. To process the bad line for an error report,
> you have to undo the final increment of thisline.

Nice try, but you're wrong; typically the report will use a 1-based value
for human consumption, so the count is actually correct after the loop
ends:

if(rc != SUCCESS)
{
  /* no adjustment required */
  fprintf(stderr, "Error on line %lu\n", (unsigned long)thisline);
}

> The left and right braces are useless unless you have a consistent
> standard that dictates their use even around loops that contain one
> statement.

And that is precisely what I have, because in my experience a
single-statement loop body soon becomes a compound-statement body, so I
might as well put the darn things in to start with, as it eliminates the
risk of forgetting them later.

> Why not just use a separate test and a break?

Because I prefer each loop to have one exit point.

> Here is better and cleaner code.

Not better, not cleaner.

> for (intLineIndex = 0; intLineIndex < intLineCount; intLineIndex++)
> if (processLine(strLine[intLineIndex]) != SUCCESS) break;

1) Clumsy variable name choice. intLineIndex needs to be of type size_t,
obviously, so the int prefix is a misnomer.

2) Your code fails to be functionally equivalent to mine, because the value
returned by the function is not available outside the loop.

3) When reporting an error, you have to adjust the line number to cater for
human readers (who, for some reason, generally don't like counting from 0).

>> > The original intent of the grandfather construct,
>> > the Do loop of Fortran, was to make processes using vectors and arrays
>> > predictable.
>>
>> Who cares? The discussion here is about C loops, not Fortran loops. If
>> you want to discuss Fortran loops, that's fine, but do it with someone
>> else, okay?
>>
> Not okay at all. This newsgroup's charter is general programming.

Right! Give the man ANOTHER five-cent cigar! And charge him another five
cents.

> Therefore discussion of programming as labor, its interface with
> society, and comparative programming language linguistics are all
> on-topic.

Wrong, wrong, and wrong.

> Defense of C and its commercial promotion is not on-topic
> under the charter.

Of course not, and I never claimed they were. But the immediate discussion
context was C's for-loops, not Fortran's Do-loops. If you want to talk
about Fortran's Do-loops, feel free, but I'm not the right person with whom
to hold that discussion.

> The charter is not what you think it is and it is not to be twisted at
> your convenience.

For once, I agree entirely, and commend that sentence to you for reflection
and edification.

>> > Basic does this because changes to control variables are not reflected
>> > in the evaluation of its For clause. C does not.
>>
>> I consider that to be a strength of C, in that it does what I expect. I
>> was surprised to find that VB.NET does things differently.
>>
> Your expectation is malformed by overexposure to C.

My expectation was actually based on the normally sound basis that if Mr
Nilges says it, it's probably wrong. That rule of thumb simply broke down
on this occasion. I use Basic so little nowadays that I cannot consider
myself to be an expert therein, which is why I don't say much about it in
this newsgroup.

> The original motivation of the Fortran Do loop was to trip through
> arrays of fixed size, known in advance, either as a constant or as a
> value calculated prior to the for loop.

I am no Fortran expert, so I don't know whether you're right or not. But I
do know this: if I wanted to find out, you are the last person on this
planet that I would consider asking (if indeed you /are/ on this planet),
because I simply don't trust a word you say.

> Because C was never designed, its for loop reinvents what its do loop,
> does.

I don't think you are competent to claim that C was never designed. I think
it's pretty obvious that C /was/ designed, and designed very carefully,
albeit with a few minor warts.

>
> You have normed what is in fact a design flaw.

I don't think it's a design flaw /at all/. But if /you/ think it's a design
flaw, why did you use it in your C code, when it's obviously trivial to
avoid it?

>> > You reminded me of a C fact which I knew when I implemented a C
>> > compiler in 1993.
>>
>> I do not believe that you are capable of writing a conforming C compiler.
>> Please provide evidence that you have done so, if you wish to be
>> persuasive.
>>
> I've clarified this. I wrote a subset compiler for business rules that
> doesn't support typedef.

I don't believe that, either. Do you have any supporting evidence for this
assertion?

> The C implementation means you have to generate code for the
> initializer,

This is just an expression, so it's not really any different from
expressions in other contexts.

> an assembly language label for the start of the actual
> loop, code to evaluate the expression in the loop condition,

Again, this is just an expression, so it's no different to before.

> a branch
> if the expression is false (branch on zero),

Yes.

> the code for the block or
> statement in the body of the for,

It's a single statement which may be a compound statement, but yes.

> and the expression in the increment
> part.

Again, this is just an expression. No different from other expressions.

> You must then generate the assembler label for the end of the
> for, and back up to the loop condition, and update the branch taken
> when the expression is false.

That's just about right, although "update the branch taken when the
expression is false" sounds wrong to me - I thought we already established
that this was simply a branch-on-zero.

> Have you ever written a compiler?

Yes, but I have never had occasion to write a C compiler.

> What is your university degree in?

I don't have a university degree, or indeed any kind of degree. I spent too
much time in terminal rooms, and not enough time in lecture halls, so I
dropped out. (No, I wasn't on a CompSci course.) But the question is an odd
one. Presumably you do have a degree, and presumably it's in CompSci, or
you wouldn't have asked. So I have a question of my own: if you have a
CompSci degree, why are you so bad at programming?

> All due respect but you may not be qualified to argue for C

You certainly aren't qualified to argue against it, because it's very clear
that you don't know it terribly well.

> (which is
> need I remind you contrary to the ng charter) if you cannot describe
> how it is compiled.

I am not arguing for C, though. I am merely rebutting the incorrect
statements you delight in making about C, because I happen to be in a good
position to do that. When you make incorrect statements about Basic, I
expect other people will argue against /those/ incorrect statements. That
doesn't mean they're defending (or attacking) Basic.

>> > I am completely not
>> > interested in your continued sniping since when I need the knowledge I
>> > go to the book.
>>
>> THEN WHY DIDN'T YOU?
>>
> Because you are not worth the time.

And that's why you write bad code? Because I'm not worth the time? Sheesh,
your manager must love you to bits.

BOSS: "Ed, this code sucks. Again! What's your excuse this time?"
EGN: "I didn't have the knowledge required."
BOSS: "So why didn't you look it up?"
EGN: "Because Richard Heathfield isn't worth the time."

Gotta love logic. Sheesh.

>> >> > Furthermore, it is only micro-inefficient in code otherwise
>> >> > well-organized to use strlen in the for condition,
>> >>
>> >> **splutter!!!**
>> >
>> > splut. Your point being?
>>
>> Can you say O(n*n)?
>
> Again, you appear to know nothing about runtime. To find the end of
> the string a single instruction, which scans a string for a character,
> is needed.

Your ignorance is dwarfed only by your stupidity. Run a profiler.

>> > If you are truly writing a truly general tool, then, consider writing
>> >
>> > for ( intLength = strlen(strInstring), intIndex1 = 0;
>> > intIndex < intLength;
>> > intIndex++ )
>>
>> Don't be silly. intLength is a hopeless name, which suggests that the
>> object is of type int whereas any competent C programmer knows that
>> strlen returns size_t.
>>
> This knowledge it is now plain is foregrounded and replaces knowledge
> independent of language.

Does that mean you didn't know the type of the value returned by strlen?

> size_t, FYI, is easily converted, probably,
> again, by a single instruction, to int.

But why bother converting it from the correct type to an incorrect type? Why
would anyone do something so stupid?

>> > But your comments on strlen suggest you may be ignorant of modern
>> > compiler optimization.
>>
[my way]
>> real 0m0.053s
>> user 0m0.040s
>> sys 0m0.020s
>>
[his way]
>>
>> real 0m0.113s
>> user 0m0.100s
>> sys 0m0.010s
>>
>> Your technique is still way slower, you see.
>
> Trivia.

Yeah, absolutely. Only a 100% difference on tiny amounts of data. And
another subscriber has posted the results of a larger test, yielding a
significant increase in the percentage difference. Typical O(n*n)
behaviour, in direct contradiction to your assertion that strlen is O(1).

>> > A good optimizer would not track invariants in loops as variables, it
>> > would extend the tracking to expressions including
>> > strlen(strInstring).
>>
>> Having seen your C code, I am not prepared to accept anything you say
>> about optimisation at face value. Note that the compiler /cannot/
>> legitimately make this assumption without understanding what strlen
>> actually /is/. That would mean putting code in specifically for
>> optimising strlen calls in the particular case where the length of the
>> string doesn't change between invocations. Are you seriously suggesting
>> this? Does anyone here know of /any/ compiler that does this?
>
> Cf. Stephen Muchnick, Advanced Compiler Design and Optimization,
> Morgan Kaufman.

Are you claiming that that book contains a conforming C implementation that
performs the stated optimisation?

Does anyone with a brain have a copy of that book, so that they can check Mr
Nilges's claim?

>> > It would add strInstring to its table of invariant variables in the
>> > for, or conversely make a short table of pointers to variables which
>> > change in the loop.
>> >
>> > If the loop does not contain any calls to external functions and no
>> > aliased references, this short table is "safe" therefore the optimizer
>> > can create in effect the above code, and a temp variable for
>> > intLength, thus avoiding discovering strlen each time.
>>
>> But strlen /is/ an external function.
>
> Might be redefined: but the compiler KNOWS when this happens, and in
> 99.999% of cases, strlen means...strlen.

Does Microsoft's C compiler perform this optimisation? Or Borland? Or gcc?
Or Intel? Or any mainstream compiler at all?

>> > In general the fact that C allows aliasing does not mean that the
>> > compiler cannot do a sort of symbolic evaluation of the text inside
>> > the loop and conclude either that "the effect of this loop is known"
>> > or else "the effect of this loop is not known".
>>
>> More to the point, it makes sense to perform this trivial optimisation in
>> one's own code, so that we don't have to assume that our end
>> user-programmer has access to an all-singing all-dancing whizzy
>> optimising compiler.
>
> The problem is that each temporary variable is a point of possible
> failure in a further evolution of the code.

I disagree, although for once you make a point that at least has a fighting
chance of being defensible. Temporary variables make it possible to write
readable, maintainable code. If they are given well-chosen names and are
managed sensibly, they can greatly /reduce/ the chance introduction of
failures during maintenance, because they can reduce the complexity of
sub-expressions.

> As the for loop expands,
> it might be used invalidly inside the for loop. The tersness of my
> example is therefore a point in its favor.

I think you overstate the danger. It's merely a string length. I won't say
that a maintenance programmer *couldn't* screw it up, but he'd have to be
pretty brain-dead to pull that trick. And the downside is a MASSIVE
reduction in performance. Performance isn't everything, by any means, but
we can't ignore it completely.

>> > It's an irresponsible hack because Kernighan if not Ritchie had as a
>> > model the Algol and Fortran work.
>>
>> Brian Kernighan wrote (most of) the *book* - not the language. As for
>> "because", are you ***serious***? There's nothing inherently
>> irresponsible about doing something differently to the way it's been done
>> before. If Dennis Ritchie had wanted to write an Algol compiler, he'd
>> have written an Algol compiler.
>>
> Nobody knew how to write an efficient Algol compiler in 1971 in a
> reasonable amount of time.

I think Dennis Ritchie could have managed it. I think Ken Thompson could
have managed it. I think Niklaus Wirth could have managed it. I'm sure
there were plenty of others around who could have done it, too.

>> > They ignored it because they were
>> > sort of passively-aggressively engaged with the computing
>> > Establishment in the context of the early 1970s, and wanted to make
>> > their own construct. They managed to screw up because the semantics of
>> > the For statement aren't clear and temporarily confuse smart people
>> > like me.
>>
>> It's a poor workman who blames his tools.
>>
> Its a worse workman who makes pronouncements about C without having
> any experience in the development of a C compiler, even a partial one.

Don't be silly. You claim to have written a partial C compiler, and yet you
don't even know the language. I don't make such a claim, and yet it's quite
evident that I know a damn sight more about it than you do. I think you
protest too much.

>> > strlen is probably generated inline.
>>
>> Inlining ***doesn't help*** here! The problem is not in the *call*, but
>> in the *code*! I mean, DUH, do you really not understand this? I can't
>> believe that even you are this stupid! The problem is that you have to
>> count the number of characters OVER and OVER and OVER. In comparison, the
>> function call overhead is trivial!
>>
> You really don't get it, do you?

I get it. I've proved that, showing test results as evidence. It's you who
seem incapable of understanding reality.

>
> The runtime doesn't count the characters in a loop until it finds a
> null character. It executes one instruction to scan for the character
> in nearly all cases.

Have you /ever/ considered checking what you say against reality?

>> > I abandoned C and adopted object oriented VB because I wanted to
>> > organize larger problems and conveniently forgot the semantics of for
>> > until you reminded me.
>>
>> It should not be assumed that, just because you say you are incapable of
>> using C to "organize larger problems", others would necessarily have the
>> same problem. C has been used successfully on extremely large problems.
>
> Yes, in part because it doesn't generate linear searches for the NUL
> character at the end of the string.

No, that's not the reason.

> Usable compilers generate a single
> instruction.

So what? The search still has to happen, even if you invoke it with a single
instruction. Just like main() still has to happen, even though it's invoked
by a single Jump-to-subroutine instruction.

Test it. Suck it and see.

> I suggest you bone up on how C is compiled in usable compilers and
> cease fantasizing.

I've actually conducted performance tests. Have you? If so, please feel free
to publish the test code and results here.

-- 
Richard Heathfield : binary@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Loading