Another day in the ordeal of cartesianProduct

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Oct 29 08:48:07 PDT 2012


On 10/28/12 8:28 AM, Peter Alexander wrote:
> On Saturday, 27 October 2012 at 13:06:09 UTC, Andrei Alexandrescu wrote:
>> On 10/27/12 8:23 AM, Peter Alexander wrote:
>>> Retrofitting some sort of structure to templates will be a Herculean
>>> task, but I think it has to happen. It is clear to me that the
>>> development process we use now (write the template, try a few
>>> instantiations, pray) is unsustainable beyond simple templates.
>>
>> It's not clear to me at all. The mechanism works very well and is more
>> expressive than alternatives used by other languages.
>
> I'm not sure I can agree it works well.
>
> For example, here's what happened with bug 8900 mentioned in the OP:
>
> std.range.zip creates a Zip object, which has a Tuple member. Tuple has
> a toString function, which calls formatElement, which calls formatValue,
> which calls formatRange, which (when there's a range of characters) has
> a code path for right-aligning the range. To right-align the range it
> needs to call walkLength.
>
> The problem arises when you zip an infinite range of characters e.g.
> repeat('a').

This proves nothing at all. So this has to do with invoking walkLength 
against an infinite range. At the time I wrote walkLength, infinite 
ranges were an experimental notion that I was ready to remove if there 
wasn't enough practical support for it. So I didn't even think of the 
connection, which means the restriction wouldn't have likely made it 
into the definition of walkLength regardless of the formalism used.

> Before pull request 880, walkLength accepted infinite ranges and just
> returned size_t.max. Pull request 880 added a constraint to walkLength
> to stop it accepting infinite ranges. Suddenly, you cannot zip a range
> of infinite chars because of a seemingly unrelated change.

The connection is obvious and is independent qualitatively of other 
cases of "if you change A and B uses it, B may change in behavior too". 
It's a pattern old as dust in programming.

Anyway, I'm not sure whether this is clear as day: expressing 
constraints as Booleans or "C++ concepts" style or Gangnam style doesn't 
influence this case in the least.

> This would have been caught if there was a unit test, but there wasn't,
> and as Dijkstra says, "testing can be a very effective way to show the
> presence of bugs, but it is hopelessly inadequate for showing their
> absence." There are probably other places that are broken, and many
> changes in the future will just introduce more bugs without tests.
>
> Maybe we have different standards for "working well", but to me at
> least, this isn't what "working well" looks like.
>
> Working well in this case would look like this:
>
> - The person that put together pull request 880 would add the template
> constraint to walkLength.
> - On the next compile he would get this error: "formatRange potentially
> calls walkLength with an infinite range." (or something along those lines).
> - The person fixes formatRange, and all is well.
>
> No need for unit tests, it's all caught as soon as possible without need
> for instantiation.

But this works today and has nothing to do with "retrofitting structure 
to templates". Nothing. Nothing.


Andrei


More information about the Digitalmars-d mailing list