Rant after trying Rust a bit

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 23 17:34:20 PDT 2015


On 7/23/2015 3:06 PM, H. S. Teoh via Digitalmars-d wrote:
> OK, I jumped into the middle of this discussion so probably I'm speaking
> totally out of context... but anyway, with regards to template code, I
> agree that it ought to be thoroughly tested by at least instantiating
> the most typical use cases (as well as some not-so-typical use cases).

I argue that every code line of the template must at least have been 
instantiated at some point by the test suite. Anything less is, frankly, 
unprofessional.


> A lot of Phobos bugs lurk in rarely-used template branches that are not
> covered by the unittests.

Generally when I work on a Phobos template, I upgrade it to 100% unit test 
coverage. This should be a minimum bar for all Phobos work. We ought to be 
ashamed of anything less.


> Instantiating all branches is only part of the solution, though. A lot
> of Phobos bugs also arise from undetected dependencies of the template
> code on the specifics of the concrete types used to test it in the
> unittests.  The template passes the unittest but when you instantiate it
> with a type not used in the unittests, it breaks. For instance, a lot of
> range-based templates are tested with arrays in the unittests. Some of
> these templates wrongly depend on array behaviour (as opposed to being
> confined only to range API operations) while their signature constraints
> indicate only the generic range API. As a result, when non-array ranges
> are used, it breaks. Sometimes bugs like this can lurk undetected for a
> long time before somebody one day happens to instantiate it with a range
> type that violates the hidden assumption in the template code.

I agree that the constraint system is not checked against the actual body of the 
template. Dicebot brought that up as well. Some attention should be paid in the 
unit tests to using types that are minimal implementations of the constraints.

That said, it is a pipe dream to believe that if something matches the function 
signatures, that it is correct and will work without ever having been tested.


> If we had a Concepts-like construct in D, where template code is
> statically constrained to only use, e.g., range API when manipulating an
> incoming type, a lot of these bugs would've been caught.
>
> In fact, I'd argue that this should be done for *all* templates -- for
> example, a function like this ought to be statically rejected:
>
> 	auto myFunc(T)(T t) { return t + 1; }
>
> because it assumes the validity of the + operation on T, but T is not
> constrained in any way, so it can be *any* type, most of which,
> arguably, do not support the + operation.

It's a valid point, but I'd counter that it'd be pretty tedious and burdensome. 
D isn't meant to be a bondage & discipline language. The failed exception 
specifications (Java and C++) comes to mind.


> If the compiler outright rejected any operation on T that hasn't been
> explicitly tested for, *then* we will have eliminated a whole class of
> template bugs. Wrong code like the last example above would be caught as
> soon as the compiler compiles the body of myFunc.

Yeah, but few would like programming in such a nagging, annoying language. Note 
that if you do instantiate with a type that doesn't support those operations, it 
isn't the end of the world - you'll still get a compile time error message.



More information about the Digitalmars-d mailing list