Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

this may not be cool but..,

454 views
Skip to first unread message

G G

unread,
Sep 3, 2014, 9:13:50 PM9/3/14
to
yes, this why there are different lang., and yes free to choose, yes if one does like it... ok i humbly, humbly accept that, but...

as i am learning C, i also grab an Ada 95 book and started learning. one thing i noticed right away was there is no equivalent to /* ... */ to handle multiple line comments. which is ok, from the perspective it's not the Ada way. ok i get it, but there are some in the group that seem to have a problem with the idea of having such a convention. problems range from not seeing the value, to how this could possibly work, the rules of how they would be use, ...
don't misunderstand, i don't want to change the "Ada way" it just seems odd.
--
--
--
--
you could of course do.

like
//
//
//
//

i guess it just odd to me that /* ... */ this causes such misgivings. multiline comments.
not '/*', '*/'.

#include <stdio.h>
int main() {
/* ignore this:
puts("*/");
*/
}

one poster posed this as a reason not to have multiline comments... but you wouldn't do this anyway would you? you would easily handle it, right? you would go... "all of what i wanted to comment out didn't happened".., the compiler alerts you to this, an error message appears, and since you put it in or are familiar with the language, you would handle this quickly, right?

a poster posted:
the Ada-83 Rationale 2.1: "Single comments
that are larger than one line are not provided. Such comments would require a
closing comment delimiter and this would again raise the dangers associated with
the (unintentional) omission of the closing delimiter: entire sections of a
program could be ignored by the compiler without the programmer realizing it, so
that the program would not mean what he thinks. Long comments can be written as
a succession of single line comments, thus combining elegance with safety."

so, as good programming style, should i adopt this thought when writing C. i mean // was added to the C lang., but i thought of it as more a convenience.

why did i post here? i come to trust and respect many of you guy's opinions. i would like to develop a good consistent style... of course being respectful to the language too. i see so many of you program in many different languages...

Ian Collins

unread,
Sep 3, 2014, 9:23:28 PM9/3/14
to
G G wrote:
> yes, this why there are different lang., and yes free to choose, yes
> if one does like it... ok i humbly, humbly accept that, but...
>
> as i am learning C, i also grab an Ada 95 book and started learning.
> one thing i noticed right away was there is no equivalent to /* ...
> */ to handle multiple line comments. which is ok, from the
> perspective it's not the Ada way. ok i get it, but there are some in
> the group that seem to have a problem with the idea of having such a
> convention. problems range from not seeing the value, to how this
> could possibly work, the rules of how they would be use, ... don't
> misunderstand, i don't want to change the "Ada way" it just seems
> odd.. -- -- --

Posting signature delimiters mid post is a good way to illustrate their
point!

Anyway, doesn't just about everyone use editors that highlight comments
these days? Event if they don't, their tests would fail wouldn't they?

--
Ian Collins

Kaz Kylheku

unread,
Sep 4, 2014, 12:42:02 AM9/4/14
to
On 2014-09-04, G G <gdo...@gmail.com> wrote:
> the Ada-83 Rationale 2.1: "Single comments
> that are larger than one line are not provided. Such comments would require a
> closing comment delimiter and this would again raise the dangers associated
> with the (unintentional) omission of the closing delimiter: entire sections
> of a program could be ignored by the compiler without the programmer
> realizing it, so that the program would not mean what he thinks. Long
> comments can be written as a succession of single line comments, thus
> combining elegance with safety.

This amusing piece of "military intelligence" can also be used to argue against
if statements. A wrong condition in the code will exclude a swath of logic
from being executed, even though the text is right there. That is to say:

if (false) {
...
...
}

is also a kind of multi line comment, and all proceeds from that.

Ike Naar

unread,
Sep 4, 2014, 2:06:53 AM9/4/14
to
On 2014-09-04, Ian Collins <ian-...@hotmail.com> wrote:
> G G wrote:
>> yes, this why there are different lang., and yes free to choose, yes
>> if one does like it... ok i humbly, humbly accept that, but...
>>
>> as i am learning C, i also grab an Ada 95 book and started learning.
>> one thing i noticed right away was there is no equivalent to /* ...
>> */ to handle multiple line comments. which is ok, from the
>> perspective it's not the Ada way. ok i get it, but there are some in
>> the group that seem to have a problem with the idea of having such a
>> convention. problems range from not seeing the value, to how this
>> could possibly work, the rules of how they would be use, ... don't
>> misunderstand, i don't want to change the "Ada way" it just seems
>> odd.. -- -- --
>
> Posting signature delimiters mid post is a good way to illustrate their
> point!

They're not.
A posting signature delimiter is newline,dash,dash,space,newline.
G G wrote newline,dash,dash,newline.
They're simply Ada comment delimiters. Illustrating his point.

Keith Thompson

unread,
Sep 4, 2014, 2:56:35 AM9/4/14
to
G G <gdo...@gmail.com> writes:
[...]
> i guess it just odd to me that /* ... */ this causes such
> misgivings. multiline comments. not '/*', '*/'.
>
> #include <stdio.h>
> int main() {
> /* ignore this:
> puts("*/");
> */
> }
>
> one poster posed this as a reason not to have multiline
> comments... but you wouldn't do this anyway would you? you would
> easily handle it, right? you would go... "all of what i wanted to
> comment out didn't happened".., the compiler alerts you to this, an
> error message appears, and since you put it in or are familiar with
> the language, you would handle this quickly, right?

The above code should not trigger an error message. Comment delimiters
are not significant within string literals.

[...]

> so, as good programming style, should i adopt this thought when
> writing C. i mean // was added to the C lang., but i thought of it as
> more a convenience.

Personally, I prefer to use // rather than /* ... */ for comments
that span multiple lines. It's easier to see at a glance that
each line is actually a comment. I've seen large block comments
delimited by /* and */ with blocks of C code somwhere in the middle;
it's can be difficult to tell that it's part of a comment.

(My preferred text editor uses the / character in search and
subsitution commands, which makes dealing with // slightly more
difficult, but I deal with it.)

Of course you can use a convention to mark each line:

/*
* This is a
* long mult-line
* comment.
*/

but a stray closing delimiter in the middle of the block can cause
problems.

On the other hand, plenty of programmers use /* ... */ for multi-line
comments, and that's a legitimate choice.

It's been suggested that /* ... */ comments are preferred for code
posted here, because some news software will fold long lines; //
comments are more likely to introduce syntax errors when that happens.

And speaking of long lines, it will be very helpful if you'll format
your articles with hard line breaks, making each line no longer than
about 72 characters. Some newsreader softwware doesn't deal well with
very long lines.

Also, a line consisting of "-- " introduces a signature, which may be
displayed differently and/or is not included automatically in followups.
Some news software (incorrectly) treats "--", without the trailing
space, as a signature delimiter. You had several such lines in your
article. If you want to use such lines in the future, indenting them:

--
--

should avoid the problem.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson

unread,
Sep 4, 2014, 2:58:04 AM9/4/14
to
My newsreader (incorrectly) treats a line consisting of "--" as a
signature delimiter, probably because some software (incorrectly)
generates them as signature delimiters. (Significant trailing
whitespace tends to be a bad idea anyway.)

G G

unread,
Sep 4, 2014, 3:16:47 AM9/4/14
to
ok, hard breaks, and indenting, no longer than 72
characters, got it.

thanks Keith,

g.

Richard Heathfield

unread,
Sep 4, 2014, 3:37:50 AM9/4/14
to
You owe me a new sarcometer. You just bent the needle around the pin.

--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

Ben Bacarisse

unread,
Sep 4, 2014, 5:31:39 AM9/4/14
to
Ike Naar <i...@iceland.freeshell.org> writes:

> On 2014-09-04, Ian Collins <ian-...@hotmail.com> wrote:
<snip>
>> Posting signature delimiters mid post is a good way to illustrate their
>> point!
>
> They're not.
> A posting signature delimiter is newline,dash,dash,space,newline.
> G G wrote newline,dash,dash,newline.

What arrived here was three without, and the fourth with, a trailing space.

--
Ben.

Ike Naar

unread,
Sep 4, 2014, 7:05:15 AM9/4/14
to
Correct, I missed the space after number four.

Kaz Kylheku

unread,
Sep 4, 2014, 9:57:48 AM9/4/14
to
On 2014-09-04, Keith Thompson <ks...@mib.org> wrote:
> G G <gdo...@gmail.com> writes:
> [...]
>> i guess it just odd to me that /* ... */ this causes such
>> misgivings. multiline comments. not '/*', '*/'.
>>
>> #include <stdio.h>
>> int main() {
>> /* ignore this:
>> puts("*/");
>> */
>> }
>>
>> one poster posed this as a reason not to have multiline
>> comments... but you wouldn't do this anyway would you? you would
>> easily handle it, right? you would go... "all of what i wanted to
>> comment out didn't happened".., the compiler alerts you to this, an
>> error message appears, and since you put it in or are familiar with
>> the language, you would handle this quickly, right?
>
> The above code should not trigger an error message. Comment delimiters
> are not significant within string literals.

String literal syntax is also not significant within comments, since
the interior isn't delimited into tokens.

The above code has a string literal which starts at "); and is unterminated.

Geoff

unread,
Sep 4, 2014, 10:04:27 AM9/4/14
to
Actually, he posted three dash, dash, newlines followed by one dash,
dash, space, newline.

Keith Thompson

unread,
Sep 4, 2014, 10:50:17 AM9/4/14
to
You're right. I really should have tried compiling that before posting.

Kaz Kylheku

unread,
Sep 4, 2014, 1:14:23 PM9/4/14
to
On 2014-09-04, Keith Thompson <ks...@mib.org> wrote:
> Kaz Kylheku <k...@kylheku.com> writes:
>> On 2014-09-04, Keith Thompson <ks...@mib.org> wrote:
>>> G G <gdo...@gmail.com> writes:
>>> [...]
>>>> i guess it just odd to me that /* ... */ this causes such
>>>> misgivings. multiline comments. not '/*', '*/'.
>>>>
>>>> #include <stdio.h>
>>>> int main() {
>>>> /* ignore this:
>>>> puts("*/");
>>>> */
>>>> }
>>>>
>>>> one poster posed this as a reason not to have multiline
>>>> comments... but you wouldn't do this anyway would you? you would
>>>> easily handle it, right? you would go... "all of what i wanted to
>>>> comment out didn't happened".., the compiler alerts you to this, an
>>>> error message appears, and since you put it in or are familiar with
>>>> the language, you would handle this quickly, right?
>>>
>>> The above code should not trigger an error message. Comment delimiters
>>> are not significant within string literals.
>>
>> String literal syntax is also not significant within comments, since
>> the interior isn't delimited into tokens.
>>
>> The above code has a string literal which starts at "); and is unterminated.
>
> You're right. I really should have tried compiling that before posting.

But it underscores the point, doesn't it! Someone who works with C regularly
can still be fooled by the sane appearance of a botched attempt to "comment
out" code instead of using the preprocessor.

August Karlstrom

unread,
Sep 4, 2014, 2:05:26 PM9/4/14
to
On 2014-09-04 08:56, Keith Thompson wrote:
> Personally, I prefer to use // rather than /* ... */ for comments
> that span multiple lines. It's easier to see at a glance that
> each line is actually a comment.I've seen large block comments
> delimited by /* and */ with blocks of C code somwhere in the middle;
> it's can be difficult to tell that it's part of a comment.

For me this is the best reason to use syntax highlighting.

> Of course you can use a convention to mark each line:
>
> /*
> * This is a
> * long mult-line
> * comment.
> */
>
> but a stray closing delimiter in the middle of the block can cause
> problems.

The drawback of using // or * at the beginning of each line in comment
paragraphs is that they will be very hard to edit unless the editor
supports automatic (hard) rewrapping. My preference is to use block
comments (/*...*/) with no (hard) line breaks. If you change the size of
the editor window the comment paragraphs will then (softly) rewrap
correctly.


-- August

Ken Brody

unread,
Sep 4, 2014, 5:06:52 PM9/4/14
to
On 9/4/2014 2:06 AM, Ike Naar wrote:
> On 2014-09-04, Ian Collins <ian-...@hotmail.com> wrote:
>> G G wrote:
[...]
>>> misunderstand, i don't want to change the "Ada way" it just seems
>>> odd.. -- -- --
>>
>> Posting signature delimiters mid post is a good way to illustrate their
>> point!
>
> They're not.
> A posting signature delimiter is newline,dash,dash,space,newline.
> G G wrote newline,dash,dash,newline.
> They're simply Ada comment delimiters. Illustrating his point.

Note that the fourth line of the OP was, in fact, "dash dash space"
surrounded by newlines.


G G

unread,
Sep 4, 2014, 5:52:44 PM9/4/14
to
Ada comments are done using, --, dashdash,
so the only way to do multiline commenting or
block comments is to place the dashes at the
beginning of each line.
so,
a block comment in Ada may be done like this
-- this is
-- how a
-- block comment
-- may be done
-- in Ada

in C,C++, Java, ... a block comment may be done like this
// this is
// how a
// block comment
// may be done

but having something like /* ... */ for block comments, multiline
comments seems to have value. well at least to me.

in C, C++, Java, ...
/*
this is
how a block comment
or multiline comment
may be done
*/

sorry, i cut and paste some text earlier. Keith explained
he was having a problem reading OP, and offered a solution.
so, in order to help those with newsreaders that don't
show it as i see it, or intended it to be seen, i reposted this
using Keith's suggestions. i hope it helps.

from OP (it was cut and pasted in original post it is typed and
hard line returned here.):

the Ada-83 Rationale 2.1: "Single comments that are larger
than one line are not provided. Such comments would require
a closing comment delimiter and this would again raise the
dangers associated with the (unintentional) omission of the
closing delimiter: entire sections of a program could be
ignored by the compiler without the programmer realizing it,
so that the program could not mean what he thinks. Long
comments can be written as a succession of single line
comments, thus combining elegance with safety."

as i said earlier, i will do it the Ada way without complaint, be-
cause that's the Ada way. it just seems odd that some of the
Ada programmers have such a hard time with the concept
of having delimiters for multiline comments.

well, change is hard for us all at some point and time. :-)

John Bode

unread,
Sep 4, 2014, 6:30:02 PM9/4/14
to
On Wednesday, September 3, 2014 8:13:50 PM UTC-5, G G wrote:
>

[snip]

>
> a poster posted:
> the Ada-83 Rationale 2.1: "Single comments
> that are larger than one line are not provided. Such comments would require a
> closing comment delimiter and this would again raise the dangers associated
> with the (unintentional) omission of the closing delimiter: entire sections of
> a program could be ignored by the compiler without the programmer realizing
> it, so that the program would not mean what he thinks. Long comments can be
> written as a succession of single line comments, thus combining elegance with
> safety."
>

I worked with Ada83 shortly after I got out of college, so I have first-hand
experience with this.

One thing to remember is back in the '80s and even into the early '90s, a lot
of us were still working on monochrome, character-based terminals such as a
VT200. Limited forms of syntax highlighting were feasible on more advanced
terminals, but not very common. It would be hard to see at a glance
whether multiple lines were commented out or not if you did the

/*
text
text
text
*/

style of commenting.

However...

Typing two dashes for every line in a doc block wasn't exactly "elegant".
It wasn't any more work than typing a leading "C" for multi-line Fortran
comments, and even today I put a leading "*" in multi-line C comments,
but for some reason two dashes added some level of visual clutter
that was more obnoxious than the others (I feel the same way about //,
honestly).

>
> so, as good programming style, should i adopt this thought when writing C.
> i mean // was added to the C lang., but i thought of it as more a convenience.
>

I'll occasionally use // for a one-off, inline comment, such as

foo( bar ); // useful comment here

or something like that. But more often than not I'll do something like

/**
* useful comment here
*/
foo( bar );

Putting the /* and */ delimiters on their own lines gives the comment some
vertical breathing space, making it easier to see. The older my eyes get,
the harder it is for me to see //-delimited comments embedded in the code.

That's strictly a matter of taste, though. There are probably at least a couple
of people in this newsgroup who would find that second style horrifying.

To whom I say, :p~~~.

>
>
> why did i post here? i come to trust and respect many of you guy's opinions.
> i would like to develop a good consistent style... of course being respectful
> to the language too. i see so many of you program in many different
> languages...

If you're developing for yourself, use whatever style works for you, as long
as you're consistent. It will change over time as you gain experience and
get more comfortable with the language.

If you're developing as part of a larger team, use whatever the team convention
is (if one exists), even if you don't like it as much.

glen herrmannsfeldt

unread,
Sep 4, 2014, 6:35:47 PM9/4/14
to
Keith Thompson <ks...@mib.org> wrote:

(snip)

> Also, a line consisting of "-- " introduces a signature, which may be
> displayed differently and/or is not included automatically in followups.
> Some news software (incorrectly) treats "--", without the trailing
> space, as a signature delimiter. You had several such lines in your
> article. If you want to use such lines in the future, indenting them:

I can probably live with that one.

I have found that some HP printers incorrectly assume that a file
that starts with % is Postscript.

(It is supposed to be files that start with %!.)

I have printed files that weren't Postscript, and that used % as
a comment on the first line, and wondered why they never came out
of the printer. (There are no PS commands, so the printer ignores
them.)

-- glen

Kaz Kylheku

unread,
Sep 4, 2014, 8:01:54 PM9/4/14
to
On 2014-09-04, G G <gdo...@gmail.com> wrote:
> Ada comments are done using, --, dashdash,
> so the only way to do multiline commenting or
> block comments is to place the dashes at the
> beginning of each line.
> so,
> a block comment in Ada may be done like this
> -- this is
> -- how a
> -- block comment
> -- may be done
> -- in Ada
>
> in C,C++, Java, ... a block comment may be done like this
> // this is
> // how a
> // block comment
> // may be done
>
> but having something like /* ... */ for block comments, multiline
> comments seems to have value. well at least to me.

Its value is compatibility with C90, that is all. If you're writing
code that has to work with C90 compilers, you comment using /*...*/
because that's all there is.

> in C, C++, Java, ...
> /*
> this is
> how a block comment
> or multiline comment
> may be done
> */

But this is an ugly style that is often avoided in favor of the following very
common style, or similar:

/*
* this is
* how a block comment
* or multiline comment
* may be done
*/

And this style says, "Boy, do I wish I had to-the-end-of-line comments in this
damned language!".

It is valuable to be able to remove some code temporarily.

A much better tool than /*...*/ for that is the preprocessor.

#if 0
ignore
me
#endif

The ignored stuff has to be valid C tokens, and any #if/#elif/#else/#endif
directives there have to nest properly:

#if 0
#ifdef BLAH
foo
#endif
#endif // ignored block ends here, not above

So if you only had // comments and #if/#ifdef in C, you would be fine.

BartC

unread,
Sep 5, 2014, 8:04:26 AM9/5/14
to
"G G" <gdo...@gmail.com> wrote in message
news:7e5a0269-a72f-40cf...@googlegroups.com...
> as i said earlier, i will do it the Ada way without complaint, be-
> cause that's the Ada way. it just seems odd that some of the
> Ada programmers have such a hard time with the concept
> of having delimiters for multiline comments.

People aren't that bothered about it, perhaps because they use a source
editor that takes care of it (select a block, click something to comment it
out, click something else to uncomment). The actual comment symbol might not
even be shown (just uses colour highlighting).

Being able to nest /*...*/ comments is just one of many things that C hasn't
got round to implementing, and probably is unlikely to for these reasons.
(There is also #if 0 .... #endif which I believe does nest.)

The advantage however of using /* ... */ in place of // or --, is that it's
less susceptible to problems from extraneous line breaks being inserted.
Unless it gets between "/" and "*". So for posting C code, I tend to use /*
... */ even for line comments.

(I also implement my own languages, which used to have multi-line comments
that nested, but recently I've taken them out, and TBH haven't really missed
them too much for the purposes of block comments.

Like /* ... */, such comments could also be used for intra-line comments, or
comments that start in the middle of one line, and end in the middle of
another, but those were hardly even used.)

--
Bartc

Keith Thompson

unread,
Sep 5, 2014, 11:28:02 AM9/5/14
to
"BartC" <b...@freeuk.com> writes:
[...]
> Being able to nest /*...*/ comments is just one of many things that C hasn't
> got round to implementing, and probably is unlikely to for these reasons.
[...]

The fact that /*...*/ comments don't nest is not an oversight;
it's deliberate. C inherited the syntax from B, which got it from
PL/I, which has far as I can tell has the same rule.

Changing the syntax so that /* is significant within /*...*/
comments would break existing code and would have no great benefit,
so it's safe to assume it will never happen.

BartC

unread,
Sep 5, 2014, 12:35:14 PM9/5/14
to
"Keith Thompson" <ks...@mib.org> wrote in message
news:lnbnqua...@nuthaus.mib.org...

> Changing the syntax so that /* is significant within /*...*/
> comments would break existing code and would have no great benefit,
> so it's safe to assume it will never happen.

Perhaps someone should do a survey of a lot of C source to find out exactly
how much would be broken. (I've just looked at a 200kloc application and
there are zero instances of */ without a matching /*.)

My guess is very little, and in a way that can be easily detected (when you
first compile with the feature turned off, but the check enabled).

Nested comments will not allow you to include a string constant containing
*/, or a // comment containing */, but that is also the case with un-nested
/* ... */ comments. This means that the following currently legal comment
will no longer work:

/* /* /* /* /* /* /* /* */

But the following equally silly and unlikely construction doesn't work
anyway:

/* */ */ */ */ */ */ */ */

--
Bartc

Keith Thompson

unread,
Sep 5, 2014, 1:23:07 PM9/5/14
to
"BartC" <b...@freeuk.com> writes:
> "Keith Thompson" <ks...@mib.org> wrote in message
> news:lnbnqua...@nuthaus.mib.org...
>> Changing the syntax so that /* is significant within /*...*/
>> comments would break existing code and would have no great benefit,
>> so it's safe to assume it will never happen.
>
> Perhaps someone should do a survey of a lot of C source to find out exactly
> how much would be broken. (I've just looked at a 200kloc application and
> there are zero instances of */ without a matching /*.)

Examining a single application, regardless of its size, is not a
good test. It might have been written under a coding standard that
forbids "/*" within a comment.

> My guess is very little, and in a way that can be easily detected (when you
> first compile with the feature turned off, but the check enabled).

More than none.

I'm fairly sure I've seen code that uses this deliberately. I don't
remember the exact details, but the idea is to comment out a chunk
of code just by adding an opening /*, something along the lines of:

a line of code;
another line of code;
/* a comment */

Inserting "/*" above the first line comments out both lines of code.

I do not suggest that this is a good idea.

Even in the absence of *deliberate* use of this feature, there
could well be code that uses it accidentally and that has been
tested and works well enough, that would be broken by a change.

One could probably construct an example that compiles without error
either with or without nested comments, but that has different
semantics (I am by no means certain of this).

In any case, the cost of leaving C's comment syntax alone is exactly
zero. The cost of changing it is non-zero, with no benefit that
I can see. It doesn't strike me as a difficult decision.

glen herrmannsfeldt

unread,
Sep 5, 2014, 6:03:22 PM9/5/14
to
Keith Thompson <ks...@mib.org> wrote:
> "BartC" <b...@freeuk.com> writes:
> [...]
>> Being able to nest /*...*/ comments is just one of many things
>> that C hasn't got round to implementing, and probably is
>> unlikely to for these reasons.
> [...]

> The fact that /*...*/ comments don't nest is not an oversight;
> it's deliberate. C inherited the syntax from B, which got it from
> PL/I, which has far as I can tell has the same rule.

Yes, it seems that the PL/I rule is that you can't have */ inside
the comment.

I don't know if there is any documentation on why it is that way.

PL/I also has a preprocessor, so one could use that, in the same
way that #if 0, is used in C. (Though I believe that the contents
has to be parsable statements and comments, unlike C.)

> Changing the syntax so that /* is significant within /*...*/
> comments would break existing code and would have no great benefit,
> so it's safe to assume it will never happen.

Yes.

-- glen

Richard Bos

unread,
Sep 6, 2014, 7:41:23 AM9/6/14
to
Keith Thompson <ks...@mib.org> wrote:

> "BartC" <b...@freeuk.com> writes:
> > "Keith Thompson" <ks...@mib.org> wrote in message
> >> Changing the syntax so that /* is significant within /*...*/
> >> comments would break existing code and would have no great benefit,
> >> so it's safe to assume it will never happen.

> > My guess is very little, and in a way that can be easily detected (when you
> > first compile with the feature turned off, but the check enabled).
>
> More than none.
>
> I'm fairly sure I've seen code that uses this deliberately. I don't
> remember the exact details, but the idea is to comment out a chunk
> of code just by adding an opening /*, something along the lines of:
>
> a line of code;
> another line of code;
> /* a comment */
>
> Inserting "/*" above the first line comments out both lines of code.

And then there's the variation on the "normal" block comment:

/************************
/* comment
/* comment
/* comment
/***********************/

Many people leave out the second to fifth /, but some don't.

Richard

Tim Rentsch

unread,
Sep 6, 2014, 12:45:38 PM9/6/14
to
Ian Collins <ian-...@hotmail.com> writes:

> Anyway, doesn't just about everyone use editors that highlight
> comments these days?

Just to supply a data point, I don't (or more precisely, I don't
enable it). I find the visual distraction greatly outweighs any
benefits. Not saying this is true for everyone, only that it
is for me (and I acknowledge that the characteristics of my
visual nervous system are not typical - to give one example, I
am partly color blind).

> Even if they don't, their tests would fail wouldn't they?

Maybe so, but for this problem I would prefer to check at
the compile step, either with a compiler option or a small
simple tool, for comment endpoint hokiness, and flag it
directly then and there.

Tim Rentsch

unread,
Sep 6, 2014, 12:58:50 PM9/6/14
to
The argument obviously doesn't hold up in regards to if(),
because the behaviors in the two cases are so different. Unlike
comments, text inside the braces of an if() are both lexed and
parsed. Any missing or extra end markers will result in a syntax
error. Also there is no possibility to mistake text inside a
string as an end marker, which will have been lexed away (but
will not have been within comments).

Ian Collins

unread,
Sep 6, 2014, 4:56:00 PM9/6/14
to
Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Even if they don't, their tests would fail wouldn't they?
>
> Maybe so, but for this problem I would prefer to check at
> the compile step, either with a compiler option or a small
> simple tool, for comment endpoint hokiness, and flag it
> directly then and there.

In my case, the compile step is nearly always "make test", so the check
is done at compile time!

--
Ian Collins

August Karlstrom

unread,
Sep 7, 2014, 7:24:51 AM9/7/14
to
On 2014-09-06 18:45, Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Anyway, doesn't just about everyone use editors that highlight
>> comments these days?
>
> Just to supply a data point, I don't (or more precisely, I don't
> enable it). I find the visual distraction greatly outweighs any
> benefits.

The default Christmas tree-like syntax highlighting of most editors is
indeed distracting. IMHO there are three syntactic entities that benefit
from syntax highlighting:

1. Comments
2. Strings
3. Function identifiers in function declarations

In my color scheme I highlight comments in dark red, strings in gray,
non-exported (static) functions using bold black text and exported
(non-static) functions using bold blue text. Being able to quickly
differentiate non-static functions from static functions is really useful.


-- August

Malcolm McLean

unread,
Sep 7, 2014, 3:05:41 PM9/7/14
to
On Sunday, September 7, 2014 12:24:51 PM UTC+1, August Karlstrom wrote:
>
> Being able to quickly differentiate non-static functions from static
> functions is really useful.
>
I agree. But I tend to bunch up all the exported functions together.

Often they're just drivers, calling the statics and maybe setting a
error flag or checking the parameters.

Nick Bowler

unread,
Sep 8, 2014, 4:08:29 PM9/8/14
to
On Thu, 04 Sep 2014 13:23:17 +1200, Ian Collins wrote:
> Anyway, doesn't just about everyone use editors that highlight comments
> these days?

My editor attempts to highlight C comments. It sometimes gets it
wrong because it does not really understand C syntax which is a bit
esoteric. For example, my editor does not highlight the second
physical source line of this comment:

//Is this comment a multi-line comment??/
Why yes, yes it is!

While this kind of nonsense is great for writing polyglots it is
reasonable for other languages to adopt a simpler comment syntax.

Geoff

unread,
Sep 8, 2014, 4:50:26 PM9/8/14
to
That might be because the line-continuation character is \, not /.

James Kuyper

unread,
Sep 8, 2014, 5:02:51 PM9/8/14
to
That's true, but I'm not quite sure why you think that's relevant, or
what conclusion you're reaching from it. My best guess is that you might
be unfamiliar with some parts of the following:

??/ is the trigraph sequence for \ (5.2.1.1p1)
"Trigraph sequences are replaced by corresponding single-character
internal representations." during translation phase 1 (5.1.1.2p1)
"Each instance of a backslash character (\) immediately followed by a
new-line character is deleted, splicing physical source lines to form
logical source lines." during translation phase 2 (5.1.1.2p2)

Therefore, at the end of translation phase 2, those two lines become
equivalent to

//Is this comment a multi-line commentWhy yes, yes it is!

Geoff

unread,
Sep 8, 2014, 6:30:29 PM9/8/14
to
I confess I have never dealt with trigraph impregnated sources and
didn't recognize it as such. I expect his syntax highlighter is broken
in the same way I am WRT trigraphs. I parsed it as a double question
mark followed by a /.

Tim Rentsch

unread,
Sep 9, 2014, 8:54:43 AM9/9/14
to
Well not quite at the same time, since running the test depends
on the compilation and also link) being successful. Having the
check be done with a compiler option or using a simple separate
tool (perhaps even as a prerequite to compiling) eliminates that
dependency.

As you can tell I'm a big fan of catching defects early. :)

Tim Rentsch

unread,
Sep 9, 2014, 10:29:55 AM9/9/14
to
August Karlstrom <fusio...@gmail.com> writes:

> On 2014-09-06 18:45, Tim Rentsch wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>
>>> Anyway, doesn't just about everyone use editors that highlight
>>> comments these days?
>>
>> Just to supply a data point, I don't (or more precisely, I don't
>> enable it). I find the visual distraction greatly outweighs any
>> benefits.
>
> The default Christmas tree-like syntax highlighting of most
> editors is indeed distracting. IMHO there are three syntactic
> entities that benefit from syntax highlighting:
>
> 1. Comments
> 2. Strings
> 3. Function identifiers in function declarations

In 3, do you mean just declarations, or does this also include
definitions?

> In my color scheme I highlight comments in dark red, strings in
> gray, non-exported (static) functions using bold black text and
> exported (non-static) functions using bold blue text. Being able
> to quickly differentiate non-static functions from static
> functions is really useful.

On the last point, why or how do you find it useful? Working in
the same file, there is no need to distinguish. Working in a
different file, I would think one would look in the interface
(.h) file, which lists just those functions that are exported.
Do you include 'static' with the definition for those functions
that are static? I think most people do, but there can be
reasons for putting 'static' only on an earlier declaration (I'm
not offering any opinion on the merits here, just noting that
this approach is a possibility).

August Karlstrom

unread,
Sep 9, 2014, 11:24:33 AM9/9/14
to
On 2014-09-09 16:29, Tim Rentsch wrote:
> August Karlstrom <fusio...@gmail.com> writes:
>> The default Christmas tree-like syntax highlighting of most
>> editors is indeed distracting. IMHO there are three syntactic
>> entities that benefit from syntax highlighting:
>>
>> 1. Comments
>> 2. Strings
>> 3. Function identifiers in function declarations
>
> In 3, do you mean just declarations, or does this also include
> definitions?

Yes, both declarations and definitions. In function declarations and
definitions the highlighting makes it easier to identify the name of the
function, something which is a bit harder in C compared to, say, Pascal.
In function definitions the highlighting also serves as a heading for
the implementation, similar to headings in an article.

>> In my color scheme I highlight comments in dark red, strings in
>> gray, non-exported (static) functions using bold black text and
>> exported (non-static) functions using bold blue text. Being able
>> to quickly differentiate non-static functions from static
>> functions is really useful.
>
> On the last point, why or how do you find it useful? Working in
> the same file, there is no need to distinguish.

When I browse through an implementation file (.c file) I will quickly
get a feeling for how many and which functions are
exported/not-exported. It is also easy to forget to make functions
static that should not be exported but here the blue color reminds me.

> Working in a
> different file, I would think one would look in the interface
> (.h) file, which lists just those functions that are exported.

Indeed.

[...]
> but there can be
> reasons for putting 'static' only on an earlier declaration (I'm
> not offering any opinion on the merits here, just noting that
> this approach is a possibility).

I didn't know you could do that. I don't see any advantage of doing so
either.


-- August

Ian Collins

unread,
Sep 9, 2014, 3:09:41 PM9/9/14
to
It's good to know you use TDD, I can't think of a better way to catch
defects early..

--
Ian Collins

Tim Rentsch

unread,
Sep 17, 2014, 9:52:03 AM9/17/14
to
Ian Collins <ian-...@hotmail.com> writes:

> Tim Rentsch wrote:
>[snip]
>> As you can tell I'm a big fan of catching defects early. :)
>
> It's good to know you use TDD, I can't think of a better way to
> catch defects early..

I realize your comment is partly tongue-in-cheek, but I would
like to give a serious statement in response.

I for one (and I hope there are others) would welcome and
appreciate a discussion of/about TDD that is lacking any
kind of advocacy. Part of what turns me off to the whole
extreme programming shtick is how its proponents can't
describe it without also saying how great it is. (To be
completely clear here, I am not lumping you in with that
group, nor do I equate TDD with extreme programming.)

So... under the generic heading of TDD in C (this being
comp.lang.c), what might you say to convey an understanding
of TDD in C to an audience that is interested but skeptical,
without any attempt to try and convince them it's a good
idea?

Tim Rentsch

unread,
Sep 17, 2014, 10:05:12 AM9/17/14
to
Interesting, thank you for the explanations.

I use (or in some cases would use) other mechanisms to
accomplish these same results. Part of the reason for
that (perhaps a large part, I'm not sure) is that I
focus on these only at select times, so most of the time
adding highlighting would be at best useless. (To be
clear, for my development process - I understand your
process is different from mine.)

> [...]
>> but there can be
>> reasons for putting 'static' only on an earlier declaration (I'm
>> not offering any opinion on the merits here, just noting that
>> this approach is a possibility).
>
> I didn't know you could do that. I don't see any advantage of
> doing so either.

The most obvious advantage is that the decision of whether to
make a function (or variable) static can be decoupled from
the point of definition. This would allow, for example, using
different headers to either export or hide various "internal"
functions. To some extent this kind of result can be achieved
using macros (eg, #define STATIC), but that approach isn't as
flexible as decoupling static-ness from definitions altogether.

Jorgen Grahn

unread,
Sep 17, 2014, 4:27:30 PM9/17/14
to
On Wed, 2014-09-17, Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Tim Rentsch wrote:
>>[snip]
>>> As you can tell I'm a big fan of catching defects early. :)
>>
>> It's good to know you use TDD, I can't think of a better way to
>> catch defects early..
>
> I realize your comment is partly tongue-in-cheek, but I would
> like to give a serious statement in response.
>
> I for one (and I hope there are others) would welcome and
> appreciate a discussion of/about TDD that is lacking any
> kind of advocacy. Part of what turns me off to the whole
> extreme programming shtick is how its proponents can't
> describe it without also saying how great it is. (To be
> completely clear here, I am not lumping you in with that
> group, nor do I equate TDD with extreme programming.)

There's also unit testing in general, which isn't the same thing as
TDD. I sometimes worry that when I advocate unit testing (which I
believe in, to some extent), people will hear me advocate TDD (which
I don't believe in at all, not as described in Kent Beck's book
anyway).

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Kaz Kylheku

unread,
Sep 17, 2014, 4:38:00 PM9/17/14
to
"I strongly advocate unit testing and regression test suites, but specifically
do not advocate the flawed 'Test Driven Design' methodology described in Kent
Beck's book."

Problem solved, except for those subject who hear what they want to hear no
matter what they hear.

Ian Collins

unread,
Sep 17, 2014, 10:58:40 PM9/17/14
to
Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Tim Rentsch wrote:
>> [snip]
>>> As you can tell I'm a big fan of catching defects early. :)
>>
>> It's good to know you use TDD, I can't think of a better way to
>> catch defects early..
>
> I realize your comment is partly tongue-in-cheek, but I would
> like to give a serious statement in response.
>
> I for one (and I hope there are others) would welcome and
> appreciate a discussion of/about TDD that is lacking any
> kind of advocacy. Part of what turns me off to the whole
> extreme programming shtick is how its proponents can't
> describe it without also saying how great it is. (To be
> completely clear here, I am not lumping you in with that
> group, nor do I equate TDD with extreme programming.)

I guess that over enthusiasm happens to all converts to something new.
After my first couple of XP projects I was always on the lookout for an
opportunity to roll out my "XP for embedded programmers" presentation.

TDD is one of the practices of XP and works best when combined with the
others. In situations where using all of the practices is impractical
or impossible (such as solo projects) it remains a useful tool.

> So... under the generic heading of TDD in C (this being
> comp.lang.c), what might you say to convey an understanding
> of TDD in C to an audience that is interested but skeptical,
> without any attempt to try and convince them it's a good
> idea?

I started out in the interested but skeptical camp having seen so many
silver bullet processes over the years (RUP anyone?) so I went along to
the inaugural New Zealand agile development conference back in 2001 with
a relatively open mind. I came away sufficiently convinced by Kent Beck
and others presentations to give the process a trial on a new project.

So 13 years on and I'm still using TDD. Why? Well mainly because it
helps me work my way into a problem. Sometimes I'm not sure how to
implement an algorithm, so I'll start with a couple of simple tests to
check my assumptions about the interface are correct. I'll then build
on those adding a little more functionality to pass each test. One
example I used to use in presentations was a polynomial curve fit. I
started with a test for fitting a horizontal line, then a sloping line,
then various quadratics. The final tests were to prove a 5th order
polynomial matched the test data I had to analyse.

Once I'm done, I know the code does what I intend it to do (it passes
the tests) and because they were added to pass tests, all of the code
paths are tested. I know that the function is lean: there's no
potentially buggy "I might need this later" code. I don't believe you
can get that level of consistent test coverage but adding tests after
the fact. The tests fully define the requirements for the function and
unlike external requirements, they can never be out of date.

--
Ian Collins

Ben Bacarisse

unread,
Sep 18, 2014, 5:49:33 AM9/18/14
to
On test driven development...
Ian Collins <ian-...@hotmail.com> writes:
> ... One
> example I used to use in presentations was a polynomial curve fit. I
> started with a test for fitting a horizontal line, then a sloping
> line, then various quadratics. The final tests were to prove a 5th
> order polynomial matched the test data I had to analyse.

Could you elaborate a bit more? It sounds like you write special code
for 1st, 2nd, 3rd, 4th and 5th order polynomial fitting, testing as you
go, rather than adding more complex tests for a general nth (or maybe
5th) order fitting function. Is that about right? And are you talking
about a "best" fit (e.g. least squares) or is the fit exact? When you
present this example, do you give the resulting code? It might help to
understand more about what consequences the process has?

> Once I'm done, I know the code does what I intend it to do (it passes
> the tests)

Is this "defintional"? I.e. do you define the purpose of the code as to
pass the tests -- no more and no less? If the data might derive from
user input, that does not seem to be enough. Is there never an external
specification that a function must meet?

> ... The tests fully define the requirements for the function
> and unlike external requirements, they can never be out of date.

That seems to answer my question but it leaves me a little confused.
Does the comment in the code and/or the documentation actually say "the
purpose of poly_fit(...) is to pass the following tests: (1) ... (2)
..."?

--
Ben.

Ian Collins

unread,
Sep 18, 2014, 6:29:18 AM9/18/14
to
Ben Bacarisse wrote:
> On test driven development...
> Ian Collins <ian-...@hotmail.com> writes:
>> ... One
>> example I used to use in presentations was a polynomial curve fit. I
>> started with a test for fitting a horizontal line, then a sloping
>> line, then various quadratics. The final tests were to prove a 5th
>> order polynomial matched the test data I had to analyse.
>
> Could you elaborate a bit more? It sounds like you write special code
> for 1st, 2nd, 3rd, 4th and 5th order polynomial fitting, testing as you
> go, rather than adding more complex tests for a general nth (or maybe
> 5th) order fitting function. Is that about right?

It was the latter, the algorithm was updated to cope with ever more
complex polynomials.

> And are you talking
> about a "best" fit (e.g. least squares) or is the fit exact? When you
> present this example, do you give the resulting code? It might help to
> understand more about what consequences the process has?

Best fit. The data was battery discharge data that I wanted to model
for a simple run time remaining algorithm.

I probably have the example stashed away somewhere, I'll see if I can
track it down.

>> Once I'm done, I know the code does what I intend it to do (it passes
>> the tests)
>
> Is this "defintional"? I.e. do you define the purpose of the code as to
> pass the tests -- no more and no less?

More or less! The tests are my (or our in team projects) interpretation
of the product requirements.

> If the data might derive from
> user input, that does not seem to be enough. Is there never an external
> specification that a function must meet?

Not the function in the code sense, but a function of the product. For
example a power system will have a configurable low voltage disconnect
function (to protect its batteries form deep discharge). So there was a
section in the product specification that detailed this behaviour. Our
tests reflected or interpretation of that requirement.

>> ... The tests fully define the requirements for the function
>> and unlike external requirements, they can never be out of date.
>
> That seems to answer my question but it leaves me a little confused.
> Does the comment in the code and/or the documentation actually say "the
> purpose of poly_fit(...) is to pass the following tests: (1) ... (2)
> ...."?

Not quite, but the header comments did refer back to the relevant
product specification section.

--
Ian Collins

Ben Bacarisse

unread,
Sep 18, 2014, 8:03:38 AM9/18/14
to
Ian Collins <ian-...@hotmail.com> writes:

> Ben Bacarisse wrote:
>> On test driven development...
>> Ian Collins <ian-...@hotmail.com> writes:
>>> ... One
>>> example I used to use in presentations was a polynomial curve fit. I
>>> started with a test for fitting a horizontal line, then a sloping
>>> line, then various quadratics. The final tests were to prove a 5th
>>> order polynomial matched the test data I had to analyse.
>>
>> Could you elaborate a bit more? It sounds like you write special code
>> for 1st, 2nd, 3rd, 4th and 5th order polynomial fitting, testing as you
>> go, rather than adding more complex tests for a general nth (or maybe
>> 5th) order fitting function. Is that about right?
>
> It was the latter, the algorithm was updated to cope with ever more
> complex polynomials.

The sounds like "the former" rather than "the latter". We may be
talking at cross purposes. If it is the former, don't you (a) get bored
before you get to the 5th order! and (b) end up with code that is so
special-cased for 5 that it's hard to read and reason about?

>> And are you talking
>> about a "best" fit (e.g. least squares) or is the fit exact? When you
>> present this example, do you give the resulting code? It might help to
>> understand more about what consequences the process has?
>
> Best fit. The data was battery discharge data that I wanted to model
> for a simple run time remaining algorithm.

Presumably, before the test-driven part starts, there is a
research-driven part that determines how the problem should be tackled?
I'm wondering how you ended up with a 5th order polynomial fitting
function rather than anything else (it seems an odd model for battery
discharge). In part I'm asking if the plan was to fit a polynomial and
you went through the various degrees to get there, or if the plan was to
fit the data, and the method gave rise to a polynomial fit.

> I probably have the example stashed away somewhere, I'll see if I can
> track it down.

That would be very interesting.

>>> Once I'm done, I know the code does what I intend it to do (it passes
>>> the tests)
>>
>> Is this "defintional"? I.e. do you define the purpose of the code as to
>> pass the tests -- no more and no less?
>
> More or less! The tests are my (or our in team projects)
> interpretation of the product requirements.
>
>> If the data might derive from
>> user input, that does not seem to be enough. Is there never an external
>> specification that a function must meet?
>
> Not the function in the code sense, but a function of the product.

Sure, but you want one to match the other in all the cases that matter,
and you test for only a finite number of cases. What is it about the
method that ensures that there are enough test cases, and that they are
the right test cases, to be reasonably sure that the code meets that
functional specification?

I may be expecting too much from one method, but my question is prompted
by "I'm done, I know the code does what I intend it to do". If the
intent is in the hands of the developer, that's not a high bar. And if
the intent is actually to meet the specification of "a function of the
product" I don't think you really know you are "done"!

<snip>
>>> ... The tests fully define the requirements for the function
>>> and unlike external requirements, they can never be out of date.
>>
>> That seems to answer my question but it leaves me a little confused.
>> Does the comment in the code and/or the documentation actually say "the
>> purpose of poly_fit(...) is to pass the following tests: (1) ... (2)
>> ...."?
>
> Not quite, but the header comments did refer back to the relevant
> product specification section.

So the function may be documented as doing something that has not been
confirmed by a test -- for example find the best 5th order polynomial
fit for some data passed to it?

--
Ben.

Ian Collins

unread,
Sep 18, 2014, 3:16:08 PM9/18/14
to
Ben Bacarisse wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Ben Bacarisse wrote:
>>> On test driven development...
>>> Ian Collins <ian-...@hotmail.com> writes:
>>>> ... One
>>>> example I used to use in presentations was a polynomial curve fit. I
>>>> started with a test for fitting a horizontal line, then a sloping
>>>> line, then various quadratics. The final tests were to prove a 5th
>>>> order polynomial matched the test data I had to analyse.
>>>
>>> Could you elaborate a bit more? It sounds like you write special code
>>> for 1st, 2nd, 3rd, 4th and 5th order polynomial fitting, testing as you
>>> go, rather than adding more complex tests for a general nth (or maybe
>>> 5th) order fitting function. Is that about right?
>>
>> It was the latter, the algorithm was updated to cope with ever more
>> complex polynomials.
>
> The sounds like "the former" rather than "the latter". We may be
> talking at cross purposes. If it is the former, don't you (a) get bored
> before you get to the 5th order! and (b) end up with code that is so
> special-cased for 5 that it's hard to read and reason about?

Maybe I wasn't quite clear: the algorithm was updated to cope with ever
more complex polynomials with out breaking the tests for simpler ones.

>>> And are you talking
>>> about a "best" fit (e.g. least squares) or is the fit exact? When you
>>> present this example, do you give the resulting code? It might help to
>>> understand more about what consequences the process has?
>>
>> Best fit. The data was battery discharge data that I wanted to model
>> for a simple run time remaining algorithm.
>
> Presumably, before the test-driven part starts, there is a
> research-driven part that determines how the problem should be tackled?

In this case, visual inspection of the data...

> I'm wondering how you ended up with a 5th order polynomial fitting
> function rather than anything else (it seems an odd model for battery
> discharge).

It's actually quite close for the type of lead acid batteries we were using.

> In part I'm asking if the plan was to fit a polynomial and
> you went through the various degrees to get there, or if the plan was to
> fit the data, and the method gave rise to a polynomial fit.

At the time, it was a case of "um, lets see if we can find a polynomial
to fit this data".

>> I probably have the example stashed away somewhere, I'll see if I can
>> track it down.
>
> That would be very interesting.
>
>>>> Once I'm done, I know the code does what I intend it to do (it passes
>>>> the tests)
>>>
>>> Is this "defintional"? I.e. do you define the purpose of the code as to
>>> pass the tests -- no more and no less?
>>
>> More or less! The tests are my (or our in team projects)
>> interpretation of the product requirements.
>>
>>> If the data might derive from
>>> user input, that does not seem to be enough. Is there never an external
>>> specification that a function must meet?
>>
>> Not the function in the code sense, but a function of the product.
>
> Sure, but you want one to match the other in all the cases that matter,
> and you test for only a finite number of cases. What is it about the
> method that ensures that there are enough test cases, and that they are
> the right test cases, to be reasonably sure that the code meets that
> functional specification?
>
> I may be expecting too much from one method, but my question is prompted
> by "I'm done, I know the code does what I intend it to do". If the
> intent is in the hands of the developer, that's not a high bar. And if
> the intent is actually to meet the specification of "a function of the
> product" I don't think you really know you are "done"!

That is very true - this particular product started life in 2002 and
development stopped a couple of years ago. At that time, quite a number
of the original requirements hadn't been implemented. No customers
wanted them!

But individual control processes (such as low volt disconnect) were well
specified and implemented. Don't forget that TDD was just a part of the
overall XP process. There were product testers writing black box tests
for the features as we were developing them. Most of the time when our
code filed their tests the problem was an ambiguity in the requirements!

> <snip>
>>>> ... The tests fully define the requirements for the function
>>>> and unlike external requirements, they can never be out of date.
>>>
>>> That seems to answer my question but it leaves me a little confused.
>>> Does the comment in the code and/or the documentation actually say "the
>>> purpose of poly_fit(...) is to pass the following tests: (1) ... (2)
>>> ...."?
>>
>> Not quite, but the header comments did refer back to the relevant
>> product specification section.
>
> So the function may be documented as doing something that has not been
> confirmed by a test -- for example find the best 5th order polynomial
> fit for some data passed to it?

I guess the header comment could have been added after the development,
but that's a recipe for not getting done...

--
Ian Collins

James Kuyper

unread,
Sep 18, 2014, 3:40:55 PM9/18/14
to
On 09/18/2014 03:15 PM, Ian Collins wrote:
> Ben Bacarisse wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>
...
>>> Best fit. The data was battery discharge data that I wanted to model
>>> for a simple run time remaining algorithm.
>>
>> Presumably, before the test-driven part starts, there is a
>> research-driven part that determines how the problem should be tackled?
>
> In this case, visual inspection of the data...
>
>> I'm wondering how you ended up with a 5th order polynomial fitting
>> function rather than anything else (it seems an odd model for battery
>> discharge).
>
> It's actually quite close for the type of lead acid batteries we were using.

Are you using any kind of theoretical model to figure out what the curve
should look like, before bothering to fit it? A fifth-order polynomial
in t diverges toward infinity for sufficiently large values of t, which
doesn't sound like a decent model for anything that could reasonably be
described by "discharge". Without knowing any of the actual details, I'd
expect declining exponential terms to play a key role.

Polynomials can be much easier to calculate efficiently than
transcendental functions - but if a good model for the process indicates
that transcendental functions should be expected, then actually fitting
to that model should produce a better fit with a smaller number of free
parameters.

James Kuyper

unread,
Sep 18, 2014, 3:41:20 PM9/18/14
to
On 09/18/2014 03:15 PM, Ian Collins wrote:
> Ben Bacarisse wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>
...
>>> Best fit. The data was battery discharge data that I wanted to model
>>> for a simple run time remaining algorithm.
>>
>> Presumably, before the test-driven part starts, there is a
>> research-driven part that determines how the problem should be tackled?
>
> In this case, visual inspection of the data...
>
>> I'm wondering how you ended up with a 5th order polynomial fitting
>> function rather than anything else (it seems an odd model for battery
>> discharge).
>
> It's actually quite close for the type of lead acid batteries we were using.

Keith Thompson

unread,
Sep 18, 2014, 4:07:42 PM9/18/14
to
On the other hand, a polynomial might be (and in this case,
apparently is) good enough over the range in which you're interested.
But it's likely to fail badly if you later need to expand that range.

I agree that taking theory into account before computing
approximations is a good idea. In this particular case, it may well
be that the polynomial that was found is the best fit to the actual
(perhaps exponential) formula, and cheaper to calculate.

Another approach might be to start with the theoretical formula, and
experiment to determine the best fitting parameters to that forumula.
If that (possibly transcendental) computation is cheap enough,
you're done. If it's not, you can throw some more math at the
problem to determine a good polynomial fit that's cheaper to compute.
Exponentials are computed using infinite series; taking just the first
few terms can give you Good Enough(tm) answers.

(I say all this based on my vanishingly tiny knowledge of what the
theoretical formula might actually look like. What I know about
battery discharge rates is that they're fast enough to annoy me.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Kaz Kylheku

unread,
Sep 18, 2014, 4:51:10 PM9/18/14
to
Such as my 7th order Fibonacci polynomial which eventually errs by
computing 42.

#include <math.h>
#include <stdio.h>

int fib(int n)
{
double out = 0.002579370;
out *= n; out -= 0.065277776;
out *= n; out += 0.659722220;
out *= n; out -= 3.381944442;
out *= n; out += 9.230555548;
out *= n; out -= 12.552777774;
out *= n; out += 7.107142857;
out *= n;
return floor(out + 0.5);
}

int main(void)
{
int i;
for (i = 0; i < 9; i++) {
printf("fib(%d) = %d\n", i, fib(i));
switch (i) {
case 7:
puts("^ So, is this calculation fib or not?");
break;
case 8:
puts("^ Answer to life, universe & everything responds negatively!");
}
}
return 0;
}

Ian Collins

unread,
Sep 19, 2014, 1:59:50 AM9/19/14
to
James Kuyper wrote:
> On 09/18/2014 03:15 PM, Ian Collins wrote:
>> Ben Bacarisse wrote:
>>> Ian Collins <ian-...@hotmail.com> writes:
>>>
> ....
>>>> Best fit. The data was battery discharge data that I wanted to model
>>>> for a simple run time remaining algorithm.
>>>
>>> Presumably, before the test-driven part starts, there is a
>>> research-driven part that determines how the problem should be tackled?
>>
>> In this case, visual inspection of the data...
>>
>>> I'm wondering how you ended up with a 5th order polynomial fitting
>>> function rather than anything else (it seems an odd model for battery
>>> discharge).
>>
>> It's actually quite close for the type of lead acid batteries we were using.
>
> Are you using any kind of theoretical model to figure out what the curve
> should look like, before bothering to fit it? A fifth-order polynomial
> in t diverges toward infinity for sufficiently large values of t, which
> doesn't sound like a decent model for anything that could reasonably be
> described by "discharge". Without knowing any of the actual details, I'd
> expect declining exponential terms to play a key role.

Well this was ten years ago... The answer was yes. The fifth-order
polynomial was a good fit for the data. As for a theoretical model, I
had two engineers who did their PhD research on battery (charge and
discharge) characteristics :)

--
Ian Collins

August Karlstrom

unread,
Sep 19, 2014, 3:45:57 AM9/19/14
to
Flexible but messy IMHO. I prefer to know a variable's or function's
export status just by looking at its definition.

-- August

Malcolm McLean

unread,
Sep 19, 2014, 3:58:07 AM9/19/14
to
On Friday, September 19, 2014 6:59:50 AM UTC+1, Ian Collins wrote:
> James Kuyper wrote:
>
> > Are you using any kind of theoretical model to figure out what the curve
> > should look like, before bothering to fit it? A fifth-order polynomial
> > in t diverges toward infinity for sufficiently large values of t, which
> > doesn't sound like a decent model for anything that could reasonably be
> > described by "discharge". Without knowing any of the actual details, I'd
> > expect declining exponential terms to play a key role.
>
> Well this was ten years ago... The answer was yes. The fifth-order
> polynomial was a good fit for the data. As for a theoretical model, I
> had two engineers who did their PhD research on battery (charge and
> discharge) characteristics :)
>
I see several issues here.

You may have theoretical reasons for thinking that battery discharge
would be described by a fifth-order polynomial. You may also therefore
have theoretical constraints on the coefficients. It might be
important for you to further explore that model, or you might just
want a clean line through the data.
You can feed any values to the fitting algorithm, but its only valid
for values which are genuinely read from the battery, which won't look
one bit like random data, or like curves produced from random
coefficients plus scatter.

Then it's very easy to write function which fits a nice polynomial
to a set of test data. The challenge is to to make it fit a nice
polynomial to every valid set of data.

What you really need is a theoretical generating model that generates
all valid discharge plots. The easy way of doing this is to use your
theoretical model to generate points on polynomials with a bit of
scatter. Then run millions of tests and see how accurately the curve
fitter recovers the underlying polynomial. The complex way is to build
a covariance matrix of point differences, then take eigenvectors.
Discard all but the bottom three eignevectors. Then you've got a data-
derived generating model on three parameters in eigenspace. Put
back into data space, and you should be able to take the curve through
all its observed permutations.

David Brown

unread,
Sep 19, 2014, 4:11:58 AM9/19/14
to
Usually for this kind of thing, a 3rd order polynomial (cubic) does the
best job. If you can't get a cubic that fits well, then a cubic spline
can be a better choice - or it is an indication that you need more
variables or more accurate measurement.

Fitting transcendentals to a set of data is typically /very/ difficult,
unless you know from the theory that they will fit (such as an
exponential decay).

But fitting any polynomial above 3rd degree is often over-fitting - you
get a curve that passes exactly through your data points, but is wildly
off-target for interpolation and extrapolation. It will be particularly
bad outside the range of the data used for fitting.

Of course, this is just general theory of curve fitting - it is quite
possible that 5th order was appropriate for the particular case in question.

Ian Collins

unread,
Sep 19, 2014, 4:36:40 AM9/19/14
to
Malcolm McLean wrote:
> On Friday, September 19, 2014 6:59:50 AM UTC+1, Ian Collins wrote:
>> James Kuyper wrote:
>>
>>> Are you using any kind of theoretical model to figure out what the curve
>>> should look like, before bothering to fit it? A fifth-order polynomial
>>> in t diverges toward infinity for sufficiently large values of t, which
>>> doesn't sound like a decent model for anything that could reasonably be
>>> described by "discharge". Without knowing any of the actual details, I'd
>>> expect declining exponential terms to play a key role.
>>
>> Well this was ten years ago... The answer was yes. The fifth-order
>> polynomial was a good fit for the data. As for a theoretical model, I
>> had two engineers who did their PhD research on battery (charge and
>> discharge) characteristics :)
>>
> I see several issues here.
>
> You may have theoretical reasons for thinking that battery discharge
> would be described by a fifth-order polynomial. You may also therefore
> have theoretical constraints on the coefficients. It might be
> important for you to further explore that model, or you might just
> want a clean line through the data.

This was a couple of evenings work ten years ago which I use to
demonstrate the TDD process, not a major piece of research!

I was trying to discuss the process, not the application domain.

One of the theses I mentioned can be found here:

http://ir.canterbury.ac.nz/handle/10092/2385

--
Ian Collins

James Kuyper

unread,
Sep 19, 2014, 7:49:27 AM9/19/14
to
That doesn't quite address my question. The fifth-order polynomial may
have been a good fit to the data over a fixed range, but no polynomial
could be a good model for battery discharge - the behavior for large
values of the dependent variable doesn't make any sense in this context.
Mentioning the engineers is not as relevant as a description of their
input into the selection of that model would have been. With their
backgrounds, they should have been familiar with more scientifically
plausible models, so if they chose (or supported the choice of) a
polynomial model, a discussion of their reasons for doing so would be
of interest to me.

I realize that you're discussing this as an example of TDD, but the TDD
discussion doesn't interest me much. The issue of how to choose the best
model in this type of situation does interest me; possibly more than it
interests you.
--
James Kuyper

Malcolm McLean

unread,
Sep 19, 2014, 8:01:33 AM9/19/14
to
To me it shows up the possible dangers of TDD.

It's easy enough to build a model that will fit a small set of test datasets. But it
won't necessarily extend to all the datasets you need to fit.

James Kuyper

unread,
Sep 19, 2014, 8:14:41 AM9/19/14
to
On 09/19/2014 04:11 AM, David Brown wrote:
...
> But fitting any polynomial above 3rd degree is often over-fitting - you
> get a curve that passes exactly through your data points, but is wildly
> off-target for interpolation and extrapolation. It will be particularly
> bad outside the range of the data used for fitting.

I once worked on a program where the designers had decided to
interpolate and extrapolate 26 data points using a polynomial with 26
coefficients. They used the Lagrange form to evaluate the polynomial
without having to determine the individual coefficients. The data
points were evenly spaced, and the model was used to extrapolate as far
as four spacings past the end of the data! I recognized the problem
immediately, but it took several years for me to figure out a way to
demonstrate the problem to the satisfaction of my bosses. The data being
fit were time values of about 18000 micro seconds. I put together a plot
showing how big of a difference it made if I just randomly shifted every
value by 1 microsecond. They quickly authorized my choice of a different
approach.
--
James Kuyper

Ian Collins

unread,
Sep 19, 2014, 3:34:54 PM9/19/14
to
The whole point of the exercise was to build a model that fitted the
test data!

As I mentioned up thread, one of the benefits of TDD is that you don't
over engineer solutions. The code does what it is required to do and no
more. If this were being developed on a time and materials basis for a
client, the client isn't interested in other data sets. If they do want
to extend the algorithm, they can. TDD and agile development in general
is all about delivering business value early through working, tested, code.

My hypothetical client may plan of having a generic model, but if the
simple one delivers them 80% of what they need, that may well chose to
divert resources elsewhere to introduce another feature. This is
exactly what happened with our controller product I mentioned elsewhere,
we were able to bring it to market several months early when it did just
enough of its planned feature set to meet a customer's requirement. As
I mentioned, because customer's requirements change, after a decade of
development there were still planned features that weren't implemented.
The time we would have wasted adding them to meet the original
requirements was better spent adding features customers actually wanted!

--
Ian Collins

Ian Collins

unread,
Sep 19, 2014, 3:49:24 PM9/19/14
to
James Kuyper wrote:
>
> I realize that you're discussing this as an example of TDD, but the TDD
> discussion doesn't interest me much. The issue of how to choose the best
> model in this type of situation does interest me; possibly more than it
> interests you.

There are times when an accurate generic model is appropriate (which is
why we put so much time and effort into battery research). Then there
are the times when a customer support engineer pops up with a collection
of logs and asks if we can help a customer with remote sites out in the
African bush tell when their batteries are about to fail. The sites
have unreliable mains power, can only be accessed by helicopter and can
we have something before a site visit next week?

This was a case of the latter.

--
Ian Collins

Jorgen Grahn

unread,
Sep 20, 2014, 5:14:03 AM9/20/14
to
I had some of my worst work experiences paying lip service to RUP,
back in the late 1990s ...

> so I went along to
> the inaugural New Zealand agile development conference back in 2001 with
> a relatively open mind. I came away sufficiently convinced by Kent Beck
> and others presentations to give the process a trial on a new project.
>
> So 13 years on and I'm still using TDD. Why? Well mainly because it
> helps me work my way into a problem. Sometimes I'm not sure how to
> implement an algorithm, so I'll start with a couple of simple tests to
> check my assumptions about the interface are correct. I'll then build
> on those adding a little more functionality to pass each test. One
> example I used to use in presentations was a polynomial curve fit. I
> started with a test for fitting a horizontal line, then a sloping line,
> then various quadratics. The final tests were to prove a 5th order
> polynomial matched the test data I had to analyse.

That's the thing about TDD that I don't like. I like to
- figure out what I think foo() should do
- write the prototype and the documentation for foo()
- write the code so that it "obviously" does what I said it
would do. Here I think in terms of invariants, and pay
attention to edge cases; watch out for overflow and so on.
- at the same time, and if it's easy, write some unit tests
for foo() too. I do that for these reasons:
- I want a reality check, if my thinking if flawed.
- To show others some example flows through foo().
- To have a starting point if I need to debug foo(), or
document a bug in it.

For me, when I rely too much on the tests, the actual code suffers. I
lose control over the invariants and so on -- it's as if I might as
well bang the keyboard at random until I by accident typed something
that would compile and pass the tests. And in the end, I usually find
it much easier to convince myself that the implementation of foo()
meets my specification, than to see that a bunch of test cases do.

Normally, at this point I'd dismiss the TDD people as hacks who
haven't learned how to program correctly, and who perhaps use flawed
languages like Smalltalk. But since I know and respect you, Ian
(based on your many postings here and in comp.lang.c++) I cannot quite
do that.

TDD must really work, for some people at least. Is it a matter of how
you were educated? My education was heavy on maths, computability and
type theory -- the Holy Grail was being able to /prove/ the code was
correct.

Also, I've worked as a (system) tester and learned to respect that
discipline too. I learned that you cannot generally trust a mere
programmer to see the big picture.

(You cannot trust a tester either, but that's a different story. The
only one you can trust is an angry paying customer.)

> Once I'm done, I know the code does what I intend it to do (it passes
> the tests) and because they were added to pass tests, all of the code
> paths are tested. I know that the function is lean: there's no
> potentially buggy "I might need this later" code. I don't believe you
> can get that level of consistent test coverage but adding tests after
> the fact.

True, adding /unit/ tests after the fact sucks. Higher levels of
tests (component and system tests of different kinds) are IMO good;
it's a "reality check" in pretty much the same way as (my take on)
unit tests above.

> The tests fully define the requirements for the function and
> unlike external requirements, they can never be out of date.

Ian Collins

unread,
Sep 20, 2014, 6:29:42 AM9/20/14
to
Jorgen Grahn wrote:
>
> For me, when I rely too much on the tests, the actual code suffers. I
> lose control over the invariants and so on -- it's as if I might as
> well bang the keyboard at random until I by accident typed something
> that would compile and pass the tests. And in the end, I usually find
> it much easier to convince myself that the implementation of foo()
> meets my specification, than to see that a bunch of test cases do.

That is a real risk, anyone who claims that TDD in isolation is a sliver
bullet is deluding themselves. This is one of the reasons agile process
such as XP rely on a collection of practices which combine to compensate
for the weaknesses in any one taken in isolation. When developers are
pairing and the team collectively owns code, there's a group of
developers to convince that the code works. Then there are the testers
to convince that the developers have correctly interpreted the requirements.

> Normally, at this point I'd dismiss the TDD people as hacks who
> haven't learned how to program correctly, and who perhaps use flawed
> languages like Smalltalk. But since I know and respect you, Ian
> (based on your many postings here and in comp.lang.c++) I cannot quite
> do that.

:)

> TDD must really work, for some people at least. Is it a matter of how
> you were educated? My education was heavy on maths, computability and
> type theory -- the Holy Grail was being able to /prove/ the code was
> correct.

I'm sure education is a factor, along with (probably more so)
personality type. Programmers with a very analytical approach to
problem solving can find it counter intuitive. My background is in
electronic engineering and I am more of a doer than a theoretician.
Even back in my student lab days I found I got the best results working
with with a partner who was happy to do the maths and write up while I
got on and did the practical work.

> Also, I've worked as a (system) tester and learned to respect that
> discipline too. I learned that you cannot generally trust a mere
> programmer to see the big picture.

True enough, good testers think about problems in a different way to
programmers. I worked with a system tester who had been a rocket
scientist back in the Soviet Union. He could be a pain at times, but he
was seldom wrong!

> (You cannot trust a tester either, but that's a different story. The
> only one you can trust is an angry paying customer.)
>
>> Once I'm done, I know the code does what I intend it to do (it passes
>> the tests) and because they were added to pass tests, all of the code
>> paths are tested. I know that the function is lean: there's no
>> potentially buggy "I might need this later" code. I don't believe you
>> can get that level of consistent test coverage but adding tests after
>> the fact.
>
> True, adding /unit/ tests after the fact sucks. Higher levels of
> tests (component and system tests of different kinds) are IMO good;
> it's a "reality check" in pretty much the same way as (my take on)
> unit tests above.

They are and they are an important part of any agile process.

--
Ian Collins

Tim Rentsch

unread,
Sep 20, 2014, 11:51:00 AM9/20/14
to
The whole point of using this technique is that any given
external definition may not have a single export status.
So the information you want just doesn't exist.

Note btw that I am only reporting the technique, not
advocating it.

August Karlstrom

unread,
Sep 20, 2014, 12:36:07 PM9/20/14
to
On 2014-09-20 17:50, Tim Rentsch wrote:
> August Karlstrom <fusio...@gmail.com> writes:
>
>> On 2014-09-17 16:04, Tim Rentsch wrote:
>>> The most obvious advantage is that the decision of whether to
>>> make a function (or variable) static can be decoupled from
>>> the point of definition. This would allow, for example, using
>>> different headers to either export or hide various "internal"
>>> functions. To some extent this kind of result can be achieved
>>> using macros (eg, #define STATIC), but that approach isn't as
>>> flexible as decoupling static-ness from definitions altogether.
>>
>> Flexible but messy IMHO. I prefer to know a variable's or
>> function's export status just by looking at its definition.
>
> The whole point of using this technique is that any given
> external definition may not have a single export status.
> So the information you want just doesn't exist.

That's true of course. At least, with my own projects I can be pretty
sure that I can tell the export status from the function definition.
This is because I use static declarations only in the context of mutual
recursion.

-- August

Tim Rentsch

unread,
Sep 20, 2014, 4:09:09 PM9/20/14
to
Let me say first that I appreciate the time and effort put in
writing your response here; I will try to do likewise in return.

Some of my (still to be written) comments may come across as
rather barbed, but that is not my intention; I strive to write
sharply, which makes things worse, but the writing is not meant
to be antagonistic.

All your comments above I put in the category of background and
personal history.

> So 13 years on and I'm still using TDD. Why? Well mainly because
> it helps me work my way into a problem.

What I'm primarily interested in is "what" and "how", not so much
"why" (which usually tends to fall in the advocacy area).

> Sometimes I'm not sure how
> to implement an algorithm, so I'll start with a couple of simple
> tests to check my assumptions about the interface are correct. I'll
> then build on those adding a little more functionality to pass each
> test. One example I used to use in presentations was a polynomial
> curve fit. I started with a test for fitting a horizontal line,
> then a sloping line, then various quadratics. The final tests were
> to prove a 5th order polynomial matched the test data I had to
> analyse.

This is good, it gives a nice example (perhaps a bit vague in
some respects but that's okay).

Let me summarize the above sketch as follows:

do {
write some tests
code a bit to address any tests not yet passed
} while( more functionality needed || tests not all passed );

Is this a fair summary of what you've described, or your usual
process, or both?

Incidentally, I'm not sure what you meant in the first sentence
about checking assumptions about the interface. What assumptions
are there to check beyond the existence of a prototype and what
types are involved? Or are you talking about extending the
behavior of an existing function, where some implementation (of
different functionality) has been done earlier?

> Once I'm done, I know the code does what I intend it to do (it
> passes the tests) and because they were added to pass tests, all
> of the code paths are tested. I know that the function is lean:
> there's no potentially buggy "I might need this later" code. I
> don't believe you can get that level of consistent test coverage
> but adding tests after the fact. The tests fully define the
> requirements for the function and unlike external requirements,
> they can never be out of date.

To me these comments all come across as why TDD is good, or
perhaps a mixture of why TDD is good and something about how you
do it. It's a sales pitch - "Not gonna say what this is exactly,
but if you use it the results will great." I don't think this is
the reaction you want.

Let's take a step back here. Pretending for a moment I know
nothing at all about TDD, I look up "Test driven development" on
wikipedia:

https://en.wikipedia.org/wiki/Test-driven_development

Considering only the writing of new code (and not maintenance or
refactoring which I think is better discussed separately), here
are the steps (all these are direct quotes, except the []'ed
text in the last item):

1. Add a test

In test-driven development, each new feature begins with
writing a test. This test must inevitably fail because it
is written before the feature has been implemented.

To write a test, the developer must clearly understand the
feature's specification and requirements.

2. Run all tests and see if the new one fails

This validates that the test harness is working correctly
and that the new test does not mistakenly pass without
requiring any new code.

3. Write some code

The next step is to write some code that causes the test to
pass.

4. Run tests

If all test cases now pass, [can move on to something else].


Some obvious questions occur to me.

First, does this match what you consider your own process to be?
(Again I am not counting any refactoring after step 4, which I
acknowledge may be counted as part of TDD but is left out of my
description here for the sake of this discussion.)

Second, the wikipedia process seems to be linear, whereas my
impression of the process you described was iterative. More
specifically, in the wikipedia process all tests (for the new
functionality) are written before any code is written, whereas
what you describe seems to alternate between them. Can you
reconcile this seeming discrepancy?

Third, do the tests written /define/ the requirements or do they
just /verify/ some external requirements? If the former, how is
it determined that the (test-defined) requirements match customer
expectations? If the latter, how is it determined that the tests
are faithful to the external requirements? (This question is
prompted in part by the statement in your last paragraph, but I
think the distinction is important in either case.)

Fourth, as tests are written before any code is written, the
tests are necessarily "black box" tests. This seems at odds
with the earlier statement about all code paths being tested.
Does this mean there is some sort of restriction about what
kinds of code may be added at each stage? Isn't there a big
advantage, in some cases, to do "white box" testing rather
than (or in addition to) "black box" testing? Is TDD really
limited to just "black box" testing? If so, where is the
slack taken up when "white box" testing is needed? If not,
what is the actual process for TDD, which would permit "white
box" testing as well as "black box" testing?

Okay I will stop here for now. If I haven't worn you out I have
some other things to ask about in the next round

Ian Collins

unread,
Sep 20, 2014, 7:34:29 PM9/20/14
to
write a test

> code a bit to address any tests not yet passed
> } while( more functionality needed || tests not all passed );
>
> Is this a fair summary of what you've described, or your usual
> process, or both?

With the amendment above, yes.

> Incidentally, I'm not sure what you meant in the first sentence
> about checking assumptions about the interface. What assumptions
> are there to check beyond the existence of a prototype and what
> types are involved? Or are you talking about extending the
> behavior of an existing function, where some implementation (of
> different functionality) has been done earlier?

In one recent example I wasn't sure which would work best form the
caller's perspective, returning results or using an in/out parameter.

>> Once I'm done, I know the code does what I intend it to do (it
>> passes the tests) and because they were added to pass tests, all
>> of the code paths are tested. I know that the function is lean:
>> there's no potentially buggy "I might need this later" code. I
>> don't believe you can get that level of consistent test coverage
>> but adding tests after the fact. The tests fully define the
>> requirements for the function and unlike external requirements,
>> they can never be out of date.
>
> To me these comments all come across as why TDD is good, or
> perhaps a mixture of why TDD is good and something about how you
> do it. It's a sales pitch - "Not gonna say what this is exactly,
> but if you use it the results will great." I don't think this is
> the reaction you want.

When you have been doing something for a white it can be hard to be
objective and identify things that aren't as obvious as they appear.
Yes.

> Second, the wikipedia process seems to be linear, whereas my
> impression of the process you described was iterative. More
> specifically, in the wikipedia process all tests (for the new
> functionality) are written before any code is written, whereas
> what you describe seems to alternate between them. Can you
> reconcile this seeming discrepancy?

I can't see where you gained that impression. Both the text (quoted
above) and the flow diagram are clear that the cycle is write a test,
write the code to pass the test, clean up, repeat. Can you point out
where you got the impression all of the tests are written before the code?

> Third, do the tests written /define/ the requirements or do they
> just /verify/ some external requirements?

The tests fit in where some process have a software requirements
specification or detailed design specification. I consider them to a
live software requirements specification.

> If the former, how is
> it determined that the (test-defined) requirements match customer
> expectations?

On my projects, the developers and the testers both work form the
product requirement specification. The unit tests are the developers
interpretation or the requirements and the acceptance tests written be
the testers are their interpretation.

> If the latter, how is it determined that the tests
> are faithful to the external requirements? (This question is
> prompted in part by the statement in your last paragraph, but I
> think the distinction is important in either case.)

The code passes the acceptance tests. if it doesn't, either the testers
or the developers misinterpreted the requirements or (more often in my
experience), the requirements were ambiguous. The effect of the to
teams writing tests for the same requirements is a good way of checking
the quality of the product requirement document.

> Fourth, as tests are written before any code is written, the
> tests are necessarily "black box" tests. This seems at odds
> with the earlier statement about all code paths being tested.

Not at all. If the only code in the function is written to pass a test,
it is almost by definition tested.

> Does this mean there is some sort of restriction about what
> kinds of code may be added at each stage?

No.

> Isn't there a big
> advantage, in some cases, to do "white box" testing rather
> than (or in addition to) "black box" testing? Is TDD really
> limited to just "black box" testing? If so, where is the
> slack taken up when "white box" testing is needed? If not,
> what is the actual process for TDD, which would permit "white
> box" testing as well as "black box" testing?

I can't see a clear distinction between "white box" and "black box"
testing in this context.

--
Ian Collins

Tim Rentsch

unread,
Sep 21, 2014, 1:11:52 PM9/21/14
to
Okay.

>> Incidentally, I'm not sure what you meant in the first sentence
>> about checking assumptions about the interface. What assumptions
>> are there to check beyond the existence of a prototype and what
>> types are involved? Or are you talking about extending the
>> behavior of an existing function, where some implementation (of
>> different functionality) has been done earlier?
>
> In one recent example I wasn't sure which would work best form the
> caller's perspective, returning results or using an in/out parameter.

I see. It isn't exactly assumptions about the interface, but
questions about how the interface should be written. That
makes sense.


>>> Once I'm done, I know the code does what I intend it to do (it
>>> passes the tests) and because they were added to pass tests, all
>>> of the code paths are tested. I know that the function is lean:
>>> there's no potentially buggy "I might need this later" code. I
>>> don't believe you can get that level of consistent test coverage
>>> but adding tests after the fact. The tests fully define the
>>> requirements for the function and unlike external requirements,
>>> they can never be out of date.
>>
>> To me these comments all come across as why TDD is good, or
>> perhaps a mixture of why TDD is good and something about how you
>> do it. It's a sales pitch - "Not gonna say what this is exactly,
>> but if you use it the results will great." I don't think this is
>> the reaction you want.
>
> When you have been doing something for a white it can be hard to be
> objective and identify things that aren't as obvious as they appear.

I should have said earlier, I didn't mean for this to be a
complaint, just to provide feedback. It might be useful
information, it just isn't what I was looking for.
The distinction I'm trying to get at has to do with what the unit
of implementation is. The wikipedia article seems to say this is
one feature (ie, per pass through the test/code loop), whereas
your description seems to say a feature may be subdivided into
smaller pieces, with each piece constituting one pass through the
test/code loop. I admit that the wikipedia article could be read
either way, this is just how it struck me. Having said all that,
let me rephrase my question. What is the unit of "work" for one
pass through the test/code loop? If that is (or can be) smaller
than "one feature", how do you choose how much to do? Your
example suggests that the amount chosen depends (or can depend)
on the implementation strategy, ie, some idea of how a function
will (or might) be implemented informs the test-writing step. Is
this a fair interpretation? If so, how common is it? Also a
related question: the example you gave seems a better fit to a
bottom-up implementation process than a top-down process - would
you say this assessment is accurate? Is your own implementation
process more top-down or bottom-up (in your estimation)?


>> Third, do the tests written /define/ the requirements or do they
>> just /verify/ some external requirements?
>
> The tests fit in where some process have a software requirements
> specification or detailed design specification. I consider them to a
> live software requirements specification.

I think a better way to say this may be that they define your
interpretation (or that of the development group) of what the
requirements say.

>> If the former, how is
>> it determined that the (test-defined) requirements match customer
>> expectations?
>
> On my projects, the developers and the testers both work form the
> product requirement specification. The unit tests are the developers
> interpretation or the requirements and the acceptance tests written be
> the testers are their interpretation.
>
>> If the latter, how is it determined that the tests
>> are faithful to the external requirements? (This question is
>> prompted in part by the statement in your last paragraph, but I
>> think the distinction is important in either case.)
>
> The code passes the acceptance tests. if it doesn't, either the
> testers or the developers misinterpreted the requirements or (more
> often in my experience), the requirements were ambiguous.

This paragraph and the two before it answer my question quite
nicely.

> The effect of the to teams writing tests for the same
> requirements is a good way of checking the quality of the
> product requirement document.

It is /a/ way. I wouldn't say it's a good way until (1) there is
some sort of metric, even if a subjective one, of what we hope
the checking process will achieve, and (2) there is at least one
(non-empty) alternative to compare it against.


>> Fourth, as tests are written before any code is written, the
>> tests are necessarily "black box" tests. This seems at odds
>> with the earlier statement about all code paths being tested.
>
> Not at all. If the only code in the function is written to pass a
> test, it is almost by definition tested.

But a single unit of implementation might contain many code
paths. How can you be sure that all paths are tested? To make
sure each code path is exercised, generally testing needs to be
white box testing rather that black box testing, ie, the tests
are written with knowledge of how the code written. Here that
is not the case. Do you see what I'm getting at here?

>> Does this mean there is some sort of restriction about what
>> kinds of code may be added at each stage?
>
> No.

So a single piece of implementation (ie, corresponding to one
test) could define as many functions as you want, with the
definition of any or all functions being as elaborate as you
want? Since the tests are written first, we can't be sure they
will exercise all the different control flows that might take
place; in general, we can't be sure that every function is even
ever called. How can these two seemingly contradictory results
be reconciled?

>> Isn't there a big
>> advantage, in some cases, to do "white box" testing rather
>> than (or in addition to) "black box" testing? Is TDD really
>> limited to just "black box" testing? If so, where is the
>> slack taken up when "white box" testing is needed? If not,
>> what is the actual process for TDD, which would permit "white
>> box" testing as well as "black box" testing?
>
> I can't see a clear distinction between "white box" and "black box"
> testing in this context.

Black box test code is written without any knowledge of the code
under test. White box test code is written with knowledge of the
code under test. White box testing therefore may examine certain
cases known to be "critical" or "near critical" for the specific
code being tested; black box testing cannot. The advantage of
black box testing is that it works no matter how a function is
implemented. The advantage of white box testing is that it may
be able to do a more thorough job of testing the code that has
actually been written.

For example, suppose we are implementing a routine to do
floating point addition in software. There may be different
code paths for corresponding to various situations - when the
exponents are the same versus when they are different, whether
or not "extraordinary rounding" may occur, whether a subnormal
result might be produced, etc. Note that these conditions are
not necessarily reflected in the output value. If test code is
written before the implementation is done, it won't know about
what these corner cases are, since they depend on how the code
is written, not any property inherent in the problem definition.
Does this make sense?

Osmium

unread,
Sep 21, 2014, 1:44:11 PM9/21/14
to

"Tim Rentsch" <t...@alumni.caltech.edu> wrote in message
news:kfnzjds...@x-alumni2.alumni.caltech.edu...

Malcolm McLean

unread,
Sep 21, 2014, 2:08:35 PM9/21/14
to
On Sunday, September 21, 2014 6:11:52 PM UTC+1, Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
> > Not at all. If the only code in the function is written to pass a
> > test, it is almost by definition tested.
>
> But a single unit of implementation might contain many code
> paths. How can you be sure that all paths are tested? To make
> sure each code path is exercised, generally testing needs to be
> white box testing rather that black box testing, ie, the tests
> are written with knowledge of how the code written. Here that
> is not the case. Do you see what I'm getting at here?
>
The idea is that you write the code to pass the test.

So we're calculating the intersection of two lines. We write code
that will calculate the intersection of 0,0 1,1 and 1,0, 0,1, and
only that intersection. All code paths are followed, because we
don't write any code that isn't designed to pass that test.

Then we add the test, intersect 0,0, 0,1 with 1,1, 1,0. That's
going to be a special case because the line are parallel. So
now we add an "if dot product equals zero" path, which that test
takes. So again, all the code paths should be followed, because
we're not adding code to cope with lines which are points, values
close to floating point precision, or other nasties which could
be thrown at us.

A perverse TDD programmer could just pass the first test by
hardcoding the result. You assume that no-one would be that stupid.
Unfortunately, you can commit the same error a bit more subtly,
by over-fitting data, for example.

Rosario193

unread,
Sep 21, 2014, 4:56:26 PM9/21/14
to
On Sun, 21 Sep 2014 11:34:09 +1200, Ian Collins wrote:
>Tim Rentsch wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>
>>> Tim Rentsch wrote:

>> Let me summarize the above sketch as follows:
>>
>> do {
>> write some tests
>
> write a test
>
>> code a bit to address any tests not yet passed
>> } while( more functionality needed || tests not all passed );
>>
>> Is this a fair summary of what you've described, or your usual
>> process, or both?
>
>With the amendment above, yes.

possible i would not speak...
i from a beginner point of view vote for this summary:

1) get a pencil and paper and imagine one algo
or to get a book and write down what that book says in some not
100% defined code

2) translate pencil and paper words or code or pictures in the
language
code of choice, and write function self find errors
all possible and impossible errors
and report the exit condition to the function that call them
or write something in the screen about data elaboration...

3) if there is something wrong: write down some test for see and
follow what code does in a debugger with some test input data

how to write test for numeric function, for find all the errors?
possibly it is more complex than the function itself or just
impossible...

the only test that find if it is right, would be the all input
possible test, and show that all output is ok
but how to do that for example just for * operation for 32 bits?

i would mutl all 32bit * 32bit values and check if result is right
using one other mult function but is it possible doing that?

Tim Rentsch

unread,
Sep 22, 2014, 11:50:42 PM9/22/14
to
Malcolm McLean <malcolm...@btinternet.com> writes:

> On Sunday, September 21, 2014 6:11:52 PM UTC+1, Tim Rentsch wrote:
>> Ian Collins <ian-...@hotmail.com> writes:
>>
>> > Not at all. If the only code in the function is written to pass a
>> > test, it is almost by definition tested.
>>
>> But a single unit of implementation might contain many code
>> paths. How can you be sure that all paths are tested? To make
>> sure each code path is exercised, generally testing needs to be
>> white box testing rather that black box testing, ie, the tests
>> are written with knowledge of how the code written. Here that
>> is not the case. Do you see what I'm getting at here?
>
> The idea is that you write the code to pass the test.
>
> So we're calculating the intersection of two lines. We write code
> that will calculate the intersection of 0,0 1,1 and 1,0, 0,1, and
> only that intersection. All code paths are followed, because we
> don't write any code that isn't designed to pass that test.
> [snip elaboration]

You missed the point of my comment. Even when writing code
intended to be only what is needed to pass a single test, there
may be arbitrarily many code paths. Obviously if the case being
added is trivial enough, like the line intersection example, that
is not likely to happen, but it easily could in cases more
typical of actual development. Suppose the unit of functionality
being added (ie, what the single added test is testing) is
splitting an AVL tree into two along a value given as an
argument. Code to do that is going to have lots more than just a
single code path.

Now it may be there that is an unstated assumption, that all
tests added are "small", so the amount of code added at each
step is also "small". But if that is an assumption it should
not be unstated. Quite the opposite: it should be proclaimed
quite loudly, because it has significant implications for the
development process. For some tasks it's okay to deal with
them using only lots of baby steps. For others, not so much.
So if TDD has an implicit (and unspoken) limitation, that
needs to be brought out in the light where folks can look at
it.

Ian Collins

unread,
Sep 23, 2014, 2:04:43 AM9/23/14
to
Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Tim Rentsch wrote:

>>> Second, the wikipedia process seems to be linear, whereas my
>>> impression of the process you described was iterative. More
>>> specifically, in the wikipedia process all tests (for the new
>>> functionality) are written before any code is written, whereas
>>> what you describe seems to alternate between them. Can you
>>> reconcile this seeming discrepancy?
>>
>> I can't see where you gained that impression. Both the text (quoted
>> above) and the flow diagram are clear that the cycle is write a test,
>> write the code to pass the test, clean up, repeat. Can you point out
>> where you got the impression all of the tests are written before the
>> code?
>
> The distinction I'm trying to get at has to do with what the unit
> of implementation is. The wikipedia article seems to say this is
> one feature (ie, per pass through the test/code loop), whereas
> your description seems to say a feature may be subdivided into
> smaller pieces, with each piece constituting one pass through the
> test/code loop.

Yes. The testes drive the implementation of the feature, one small step
at a time. As I attempted to illustrate with my curve fitting example,
the functionality of the routine grows with each test. So the unit of
implementation is small, say the step form fitting a horizontal straight
line to a sloping one.

> I admit that the wikipedia article could be read
> either way, this is just how it struck me. Having said all that,
> let me rephrase my question. What is the unit of "work" for one
> pass through the test/code loop? If that is (or can be) smaller
> than "one feature", how do you choose how much to do?

The choice is subjective, my rule is it should be small enough to
discard if it breaks something. This normally means just a few lines of
code. I try and avoid hard and fast rules here and prefer to let the
team find their own sweet spot.

> Your
> example suggests that the amount chosen depends (or can depend)
> on the implementation strategy, ie, some idea of how a function
> will (or might) be implemented informs the test-writing step. Is
> this a fair interpretation?

It can do, yes. I guess that's just human nature.

> If so, how common is it?

I can't really answer that, but it's something I try to avoid. It's not
uncommon to find a better solution as you go.

> Also a
> related question: the example you gave seems a better fit to a
> bottom-up implementation process than a top-down process - would
> you say this assessment is accurate? Is your own implementation
> process more top-down or bottom-up (in your estimation)?

I've never really though of it in those terms. It's top down in the
sense that we can start with fairly high level requirements (the product
specification).

>>> Third, do the tests written /define/ the requirements or do they
>>> just /verify/ some external requirements?
>>
>> The tests fit in where some process have a software requirements
>> specification or detailed design specification. I consider them to a
>> live software requirements specification.
>
> I think a better way to say this may be that they define your
> interpretation (or that of the development group) of what the
> requirements say.

It is.

<snip>

>> The effect of the to teams writing tests for the same
>> requirements is a good way of checking the quality of the
>> product requirement document.
>
> It is /a/ way. I wouldn't say it's a good way until (1) there is
> some sort of metric, even if a subjective one, of what we hope
> the checking process will achieve, and (2) there is at least one
> (non-empty) alternative to compare it against.

The alternative is the dreaded formal review. We preferred to review as
we coded (we being the developers and the testers). We always had
access to the product owner, so we could clarify any issues with the
requirements when we found them.

>>> Fourth, as tests are written before any code is written, the
>>> tests are necessarily "black box" tests. This seems at odds
>>> with the earlier statement about all code paths being tested.
>>
>> Not at all. If the only code in the function is written to pass a
>> test, it is almost by definition tested.
>
> But a single unit of implementation might contain many code
> paths. How can you be sure that all paths are tested?

By avoiding units of implementation might contain many code paths!

> To make
> sure each code path is exercised, generally testing needs to be
> white box testing rather that black box testing, ie, the tests
> are written with knowledge of how the code written.

Unless the code path is added to pass a test...

> Here that
> is not the case. Do you see what I'm getting at here?

I think you are missing the point that a code path is added to pass a test.

>>> Does this mean there is some sort of restriction about what
>>> kinds of code may be added at each stage?
>>
>> No.
>
> So a single piece of implementation (ie, corresponding to one
> test) could define as many functions as you want, with the
> definition of any or all functions being as elaborate as you
> want?

That's a recipe for disaster, or at least poor test coverage. Our first
attempt went down this route and it make for a maintenance headache.

> Since the tests are written first, we can't be sure they
> will exercise all the different control flows that might take
> place; in general, we can't be sure that every function is even
> ever called. How can these two seemingly contradictory results
> be reconciled?

Discipline.
It does.

--
Ian Collins

Les Cargill

unread,
Sep 23, 2014, 8:28:28 AM9/23/14
to
TDD is simply another discipline. It's not important
that you have closed, provable tests. It's simply a
matter of due diligence.

One way to "do" TDD is to add instrumentation counters to
the code, run test vectors against it, then do basic
invariant analysis on the counters.

This means you have to somehow serialize the instrumentation -
those counters don't do you any good laying in memory.

This will frequently inspire despair :)

--
Les Cargill

Phil Carmody

unread,
Sep 23, 2014, 6:09:19 PM9/23/14
to
David Brown <david...@hesbynett.no> writes:
> Fitting transcendentals to a set of data is typically /very/ difficult,
> unless you know from the theory that they will fit (such as an
> exponential decay).

From what I've read on the matter (which is probably little more than NR,
and papers by Kahan or Goldberg) exponentials are notoriously hard to fit,
even if you know it's the correct model, at least from from a numerical
analysis point of view.

Phil
--
The best part of re-inventing the wheel is that you get to pick how
many sides the new one has. -- egcagrac0 on SoylentNews

Phil Carmody

unread,
Sep 23, 2014, 6:14:14 PM9/23/14
to
"Numerical stability" was the phrase you were after. They clearly only
had one employee who was familiar with the concept.

A man walks into an error bar...

Robert Wessel

unread,
Sep 23, 2014, 7:47:48 PM9/23/14
to
On Sun, 21 Sep 2014 10:11:40 -0700, Tim Rentsch
<t...@alumni.caltech.edu> wrote:

>Black box test code is written without any knowledge of the code
>under test. White box test code is written with knowledge of the
>code under test. White box testing therefore may examine certain
>cases known to be "critical" or "near critical" for the specific
>code being tested; black box testing cannot. The advantage of
>black box testing is that it works no matter how a function is
>implemented. The advantage of white box testing is that it may
>be able to do a more thorough job of testing the code that has
>actually been written.
>
>For example, suppose we are implementing a routine to do
>floating point addition in software. There may be different
>code paths for corresponding to various situations - when the
>exponents are the same versus when they are different, whether
>or not "extraordinary rounding" may occur, whether a subnormal
>result might be produced, etc. Note that these conditions are
>not necessarily reflected in the output value. If test code is
>written before the implementation is done, it won't know about
>what these corner cases are, since they depend on how the code
>is written, not any property inherent in the problem definition.
>Does this make sense?


In a case like that you really need both. It's too easy for white box
tests to get "captured" by the specifics of the code under test. And
black box tests won't test the algorithmic "corners" well.

glen herrmannsfeldt

unread,
Sep 23, 2014, 7:52:21 PM9/23/14
to
Phil Carmody <thefatphi...@yahoo.co.uk> wrote:
> David Brown <david...@hesbynett.no> writes:
>> Fitting transcendentals to a set of data is typically /very/ difficult,
>> unless you know from the theory that they will fit (such as an
>> exponential decay).

> From what I've read on the matter (which is probably little more than NR,
> and papers by Kahan or Goldberg) exponentials are notoriously hard to fit,
> even if you know it's the correct model, at least from from a numerical
> analysis point of view.

And you have to know that it is an exponential.

I haven't finished yet, but I have a book called "Black Swan".

-- glen

Morris Dovey

unread,
Sep 23, 2014, 8:50:33 PM9/23/14
to
/* Exponential fit */

fabls_t *fabls_e(hwrd n,double *px,double *py,fabls_t *p)
{ static fabls_t result;
double a1,a2,denom,dy,s1,s2,s3,s4,x,y,z;
hwrd i;

if (NULL == p) p = &result;
s1 = s2 = s3 = s4 = z = 0;
for (i=0; i<n; i++)
{ x = px[i];
y = alog(py[i]);
s1 += x;
s2 += x * x;
s3 += y;
s4 += x * y;
}
if (denom = n * s2 - s1 * s1)
{ a1 = (s3 * s2 - s1 * s4) / denom;
a2 = (n * s4 - s3 * s1) / denom;
for (i=0; i<n; i++)
{ dy = alog(py[i]) - (a2 * px[i] + a1);
z += dy * dy;
}
p->type = 'E';
p->s = sqrt(z / (n - 1));
p->a1 = a1;
p->a2 = a2;
}
else p = NULL;
return p;
}

Works for me. This is extracted from my ancient least squares analysis
program that fits linear, quadratic, exponential, logarithmic, and power
functions to a supplied set of (x,y) values and prints the resulting
functions and standard deviations. Been thinking that one day I should
add the ability to plot the points and curves into a png file...

If the data is really lousy, it can become difficult to choose the best
fit, but I don’t think that’s a program deficiency. :-/

--
Morris Dovey
http://www.iedu.com/Solar/
http://www.facebook.com/MorrisDovey

Tim Rentsch

unread,
Sep 25, 2014, 12:25:45 PM9/25/14
to
Ian Collins <ian-...@hotmail.com> writes:

[a nice long response]

A short interim post just to say I have read through your
comments and would like to read them again and think a bit
more before giving a more contentful reply. (Also to repeat
that I appreciate the time and effort put in.)

Ike Naar

unread,
Sep 25, 2014, 5:16:59 PM9/25/14
to
Let's take a very simple function as an example:
min(x,y) which computes the minimum of (integer) x and y.

This implementation

int min(int x, int y) { return x; }

is obviously wrong.
But (do I understand you correctly?) according to the TDD philosophy
that implementation is perfectly okay when the test set consists of

{ min(0,0) = 0, min(0,1) = 0, min(1,1) = 1 } ?

And, when the test set is extended with

{ min(1,0) = 0 } ,

the implementation that was perfectly okay at first
suddenly turns into an implementation that is wrong,
only because the test set has changed?

And, at that point, another blatantly wrong implementation such as

int min(int x, int y) { return x * y; }

becomes perfectly okay ?

If that is the case, I have serious doubts on the merits of TDD.

Tim Rentsch

unread,
Sep 26, 2014, 1:21:44 AM9/26/14
to
Robert Wessel <robert...@yahoo.com> writes:

> On Sun, 21 Sep 2014 10:11:40 -0700, Tim Rentsch
> <t...@alumni.caltech.edu> wrote:
>
>> [black box versus white box testing]
>
> In a case like that you really need both. It's too easy for white
> box tests to get "captured" by the specifics of the code under
> test. And black box tests won't test the algorithmic "corners"
> well.

I more or less agree. What I was wondering is where or how the
different modes fit within a TDD processs.

Tim Rentsch

unread,
Sep 26, 2014, 1:48:25 AM9/26/14
to
Maybe so, but the question is what /is/ the actual process,
and how is it carried out in practice by its practitioners.

> It's not important that you have closed, provable tests. It's
> simply a matter of due diligence.

That's salesman talk. "If you do it right, it will work really
well and do great things for you." If what a process is
supposed to be is not at least somewhat well-defined, it's
snake oil.

> One way to "do" TDD is to add instrumentation counters to the
> code, run test vectors against it, then do basic invariant
> analysis on the counters. [snip elaboration]

Probably some TDD proponents would agree with that, but it
certainly does not seem consistent with the process defined on
the Test driven development page on wikipedia. Part of what I'm
trying to find out is what the general consensus is as to what a
TDD process allows and what it more or less excludes, or to what
extent there is widespread consensus. Hearing rather divergent
views about what testing methods are thought to be "TDD-okay"
would not raise my confidence in adopting a TDD approach.

David Brown

unread,
Sep 26, 2014, 4:21:07 AM9/26/14
to
As far as I understand it, the implementation is correct here but the
tests are not good enough.

Different development models demand different skills from people along
the chain. Some development models work from simple specifications and
rely on the programmer to understand the real issues. Others work from
very detailed specifications and expect the programmer to implement the
specifications with little understanding or interpretation. In TDD,
much of the effort is done by the test designer who must understand
exactly what is needed, and construct appropriate tests.


Ian Collins

unread,
Sep 26, 2014, 5:12:31 AM9/26/14
to
That's pretty much correct. Sometimes (but obviously not here!) an
incomplete implementation is good enough for a particular use case. A
partial implementation of a function (think of something like printf
formatting) might be good enough for an early release (say one that
didn't use floating point). The functionality requiring a fuller
implementation may only be needed in a later release, or not at all if
the customer decides they don't want it. That's part of the underlying
philosophy of any agile process - only implement (and test) what you
need for the current iteration.

> Different development models demand different skills from people along
> the chain. Some development models work from simple specifications and
> rely on the programmer to understand the real issues. Others work from
> very detailed specifications and expect the programmer to implement the
> specifications with little understanding or interpretation. In TDD,
> much of the effort is done by the test designer who must understand
> exactly what is needed, and construct appropriate tests.

Not quite. In TDD the (unit) test designer is the programmer. In all
of the agile processes I'm familiar with the programmers are in close
contact with the product owner or customer, so they tend to work from
simple specifications and have a good understanding of the customer's
requirements.

--
Ian Collins

Malcolm McLean

unread,
Sep 26, 2014, 5:14:04 AM9/26/14
to
As I understand it, it's not that the test isn't good enough, but the system has
broken down because there happens to be a wrong solution which passes
the test, but isn't a case of missing functionality.
The main real situation where that would happen is in machine learning/
data fitting functions, where notoriously algorithms work on test data
but fail to generalise. Any programmer can subvert TDD by hardcoding a
result that simply passes the test, you've got to assume that the programmer
won't do that.

Ian Collins

unread,
Sep 26, 2014, 5:16:28 AM9/26/14
to
Don't forget TDD is usually used in a agile, more specifically XP
project. So there will always be more than one layer of testing. The
biggest project I ran had three: developer TDD tests, tester written
customer acceptance tests and system release tests. Our aim (which we
came very close to achieving) was zero field defects.

--
Ian Collins

David Brown

unread,
Sep 26, 2014, 6:27:42 AM9/26/14
to
I would say that the test is not good enough, because it doesn't
represent the real use cases.

> The main real situation where that would happen is in machine learning/
> data fitting functions, where notoriously algorithms work on test data
> but fail to generalise. Any programmer can subvert TDD by hardcoding a
> result that simply passes the test, you've got to assume that the programmer
> won't do that.
>

Ideally, I suppose, the person creating the test and test data is not
the same as the person implementing the solution, and they hold back
some of their test cases until final tests.

But you always have to assume that people will do their best, and not
try to "cheat" in some way.


Richard Heathfield

unread,
Sep 26, 2014, 6:29:11 AM9/26/14
to
Ike Naar wrote:

<snip>

> But (do I understand you correctly?) according to the TDD philosophy
> that implementation is perfectly okay when the test set consists of
>
> { min(0,0) = 0, min(0,1) = 0, min(1,1) = 1 } ?
>
> And, when the test set is extended with
>
> { min(1,0) = 0 } ,
>
> the implementation that was perfectly okay at first
> suddenly turns into an implementation that is wrong,
> only because the test set has changed?
>
> And, at that point, another blatantly wrong implementation such as
>
> int min(int x, int y) { return x * y; }
>
> becomes perfectly okay ?
>
> If that is the case, I have serious doubts on the merits of TDD.

But isn't this the whole point of pair programming?

Programmer A: Ha! I can just write... <bone-headed code> and it'll pass the
test!
Programmer B: Very funny. Now do it properly.

--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

Les Cargill

unread,
Sep 26, 2014, 9:03:14 PM9/26/14
to
There can't be a universal description because everything is
different. But the basic is "have test vectors, use
them, possibly as part of the build process."

>> It's not important that you have closed, provable tests. It's
>> simply a matter of due diligence.
>
> That's salesman talk. "If you do it right, it will work really
> well and do great things for you." If what a process is
> supposed to be is not at least somewhat well-defined, it's
> snake oil.
>


It's not salesman talk at all. It's just one practice you can use to
verify your code. It's a matter of whether you'd rather find the bugs
in unit test or in integration. That's what I mnean by "due diligence" -
what's your pain threshold for finding something in integration?

For example - I was once a week "late" because of unit tests. The
rest of the team became *six months* "late" because they didn't do unit
tests. I literally watched for that long - not completely
true, I built some other sc aoffolding that proved the hardware
wouldn't work. :)

I never could get the hang of working by the hour :)

>> One way to "do" TDD is to add instrumentation counters to the
>> code, run test vectors against it, then do basic invariant
>> analysis on the counters. [snip elaboration]
>
> Probably some TDD proponents would agree with that, but it
> certainly does not seem consistent with the process defined on
> the Test driven development page on wikipedia.

Oh, I don't pay any attention to that sort of thing. *Now*
I understand - yes, there are "paradigm" people all over the place
who can turn an otherwise Useful tool into some sort of jihad.

The parts of TDD that are not obvious should probably be ignored.

People don't seem to have enuogh to do these days.

> Part of what I'm
> trying to find out is what the general consensus is as to what a
> TDD process allows and what it more or less excludes, or to what
> extent there is widespread consensus.

I dunno anything about that. I figure on leaving a span of time for
testing with a discounted estimate of the cost per defect I would
have otherwise missed.

Go off and figure a lot of the edges of your code, write some sorta
test vector generator and go to it. You might even wanna integrate
coverage testing into something like this.

> Hearing rather divergent
> views about what testing methods are thought to be "TDD-okay"
> would not raise my confidence in adopting a TDD approach.
>

I'd have to agree there.

--
Les Cargill

Les Cargill

unread,
Sep 26, 2014, 9:05:31 PM9/26/14
to
SO one guy I worked with noted that the tests and code are basically
"duals" of each other. He called the process of modifying them to
achieve a well-covered and clean result "simulated annealing", which
was probably evidence he was a physicist.

--
Les Cargill

Les Cargill

unread,
Sep 26, 2014, 9:07:54 PM9/26/14
to
David Brown wrote:
> On 26/09/14 11:13, Malcolm McLean wrote:
<snip>
>
> But you always have to assume that people will do their best, and not
> try to "cheat" in some way.
>
>

But putting in a temporary "cheat", marked with a //TODO then
carefully cleaning all those up is probably okay. It
also means you can "find . -name "*.[c]" | xargs grep TODO" and
have a quick metric of completion.

--
Les Cargill

Richard Heathfield

unread,
Sep 27, 2014, 3:10:21 AM9/27/14
to
Ian Collins wrote:
> Tim Rentsch wrote:
<snip>
>> The distinction I'm trying to get at has to do with what the unit
>> of implementation is. The wikipedia article seems to say this is
>> one feature (ie, per pass through the test/code loop), whereas
>> your description seems to say a feature may be subdivided into
>> smaller pieces, with each piece constituting one pass through the
>> test/code loop.
>
> Yes. The testes drive the implementation of the feature, one small step
> at a time.

My apologies, Ian, but the question must be asked...

Does it hurt?

Ian Collins

unread,
Sep 27, 2014, 3:17:44 AM9/27/14
to
Richard Heathfield wrote:
> Ian Collins wrote:
>> Tim Rentsch wrote:
> <snip>
>>> The distinction I'm trying to get at has to do with what the unit
>>> of implementation is. The wikipedia article seems to say this is
>>> one feature (ie, per pass through the test/code loop), whereas
>>> your description seems to say a feature may be subdivided into
>>> smaller pieces, with each piece constituting one pass through the
>>> test/code loop.
>>
>> Yes. The testes drive the implementation of the feature, one small step
>> at a time.
>
> My apologies, Ian, but the question must be asked...
>
> Does it hurt?

Yes, if you try and do too much in one go!

--
Ian Collins

Tim Rentsch

unread,
Sep 27, 2014, 6:37:36 AM9/27/14
to
Ian Collins <ian-...@hotmail.com> writes:

> Tim Rentsch wrote:
>> Robert Wessel <robert...@yahoo.com> writes:
>>
>>> On Sun, 21 Sep 2014 10:11:40 -0700, Tim Rentsch
>>> <t...@alumni.caltech.edu> wrote:
>>>
>>>> [black box versus white box testing]
>>>
>>> In a case like that you really need both. It's too easy for white
>>> box tests to get "captured" by the specifics of the code under
>>> test. And black box tests won't test the algorithmic "corners"
>>> well.
>>
>> I more or less agree. What I was wondering is where or how the
>> different modes fit within a TDD processs.
>
> Don't forget TDD is usually used in a agile, more specifically XP
> project. [snip elaboration]

To my way of thinking this makes the situation worse, not
better. I'm trying to understand what what people mean by
"TDD" without having to know about a bunch of related
processes. Can TDD be defined without reference to other
development processes or practices? If yes, that's what I
am trying to find out. If no, what is the minimal set of
related activities for which it makes sense to talk about
TDD in a well-defined way?

I should add, I understand that there may be synergistic
effects of using other practices along with TDD. But right
now I'm just trying to find out what people mean by the
term (and whether different people mean different things,
how fuzzy or sharp the definition(s) is(are), etc), not
what the synergies might be.

Tim Rentsch

unread,
Sep 27, 2014, 7:03:59 AM9/27/14
to
Les Cargill <lcarg...@comcast.com> writes:

> Tim Rentsch wrote:
>> Les Cargill <lcarg...@comcast.com> writes:
>>
>>> Tim Rentsch wrote:
>>>> Malcolm McLean <malcolm...@btinternet.com> writes:
>>>>
>>>>> On Sunday, September 21, 2014 6:11:52 PM UTC+1, Tim Rentsch wrote:
>>>>>> Ian Collins <ian-...@hotmail.com> writes:

> [an extensive set of responses]

I'm still not sure if we're completely understanding each
other. But I wanted to say I appreciate the comments, I
do see more where you're coming from.

David Brown

unread,
Sep 27, 2014, 9:58:46 AM9/27/14
to
I wouldn't count a "ToDo" as a cheat - it's a reminder to oneself and
others that more code is needed there. If someone submits code as
finished while it still contains ToDo's, then they need to explain them
- if they gloss over them then it is perhaps "cheating".

Your find would be better as:

find . -name "*.[ch]" | xargs grep -i todo

Les Cargill

unread,
Sep 27, 2014, 4:14:57 PM9/27/14
to
Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Tim Rentsch wrote:
>>> Robert Wessel <robert...@yahoo.com> writes:
>>>
>>>> On Sun, 21 Sep 2014 10:11:40 -0700, Tim Rentsch
>>>> <t...@alumni.caltech.edu> wrote:
>>>>
>>>>> [black box versus white box testing]
>>>>
>>>> In a case like that you really need both. It's too easy for white
>>>> box tests to get "captured" by the specifics of the code under
>>>> test. And black box tests won't test the algorithmic "corners"
>>>> well.
>>>
>>> I more or less agree. What I was wondering is where or how the
>>> different modes fit within a TDD processs.
>>
>> Don't forget TDD is usually used in a agile, more specifically XP
>> project. [snip elaboration]
>
> To my way of thinking this makes the situation worse, not
> better. I'm trying to understand what what people mean by
> "TDD" without having to know about a bunch of related
> processes. Can TDD be defined without reference to other
> development processes or practices?

I would think not.

> If yes, that's what I
> am trying to find out. If no, what is the minimal set of
> related activities for which it makes sense to talk about
> TDD in a well-defined way?
>

Processes are cultural artifacts and you'll just
have to negotiate with everybody on the team for
what's proper and what isn't.

The idea is to control "negative externalities"
from your activities.

> I should add, I understand that there may be synergistic
> effects of using other practices along with TDD. But right
> now I'm just trying to find out what people mean by the
> term (and whether different people mean different things,
> how fuzzy or sharp the definition(s) is(are), etc), not
> what the synergies might be.
>

People mean what they mean exactly, no more or no less
( with apologies to Lewis Carroll )

--
Les Cargill

Ian Collins

unread,
Sep 28, 2014, 4:12:59 PM9/28/14
to
Tim Rentsch wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>> Tim Rentsch wrote:
>>> Robert Wessel <robert...@yahoo.com> writes:
>>>
>>>> On Sun, 21 Sep 2014 10:11:40 -0700, Tim Rentsch
>>>> <t...@alumni.caltech.edu> wrote:
>>>>
>>>>> [black box versus white box testing]
>>>>
>>>> In a case like that you really need both. It's too easy for white
>>>> box tests to get "captured" by the specifics of the code under
>>>> test. And black box tests won't test the algorithmic "corners"
>>>> well.
>>>
>>> I more or less agree. What I was wondering is where or how the
>>> different modes fit within a TDD processs.
>>
>> Don't forget TDD is usually used in a agile, more specifically XP
>> project. [snip elaboration]
>
> To my way of thinking this makes the situation worse, not
> better. I'm trying to understand what what people mean by
> "TDD" without having to know about a bunch of related
> processes. Can TDD be defined without reference to other
> development processes or practices? If yes, that's what I
> am trying to find out. If no, what is the minimal set of
> related activities for which it makes sense to talk about
> TDD in a well-defined way?

I thought that part was pretty clear.

Write a failing test
Write the code to pass the test
Commit
Clean up
Repeat.

> I should add, I understand that there may be synergistic
> effects of using other practices along with TDD. But right
> now I'm just trying to find out what people mean by the
> term (and whether different people mean different things,
> how fuzzy or sharp the definition(s) is(are), etc), not
> what the synergies might be.

I'm sure different people don't mean different things. They may
implement the details differently, that's to be expected with different
languages, tools and team dynamics. Despite the minor differences if
you get a large group of XP developers in a room, they will all
understand each other's process.

Agile processes aren't intended to be rigid follow the recipe
methodologies, they are flexible. Teams use them as the foundation for
their own process. They wouldn't be agile otherwise, would they?

--
Ian Collins
It is loading more messages.
0 new messages