Please do not use 'auto' return types without thoroughly describing the interface

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Dec 27 16:36:59 UTC 2017


On Tue, Dec 26, 2017 at 11:28:56AM +0000, Mark via Digitalmars-d wrote:
> On Monday, 25 December 2017 at 22:48:39 UTC, H. S. Teoh wrote:
> > While I agree that all template parameters ought to be documented
> > and all auto return types thoroughly described, I disagree with
> > explicit naming of auto return types. The whole point of auto return
> > types is to return an *opaque* type that user code should not depend
> > on, apart from what the documentation says you can do with the type.
> > It's a matter of encapsulation, i.e., "you can do X, Y, Z with the
> > return value of this function, everything else is none of your
> > business". Or, in other words, if your code can't possibly work
> > without knowing the explicit type of the return value, then you're
> > doing something wrong (using the function wrongly).
> > 
> > T
> 
> Maybe we can document the interface of the return type using signature
> constraints? For instance, for the function:
> 
> auto map(Range)(Range r) if (isInputRange!(Unqual!Range));
> 
> we'd add the following to its constraints:
> 
> isInputRange!(ReturnType!(map!R))
> 
> However, this does not compile at the moment. I'm not sure why.

I'm not sure why either, but signature constraints are intended to be
used for constraining the range of incoming template arguments that the
template will accept. It's not intended to establish a contract on what
the template is going to produce when instantiated with those arguments,
though this could well be an enhancement request. Perhaps this should be
filed in bugzilla so that it won't get forgotten.

The best we can do currently, which unfortunately won't show up in the
docs, is to use a static assert to force compilation failure when the
return type doesn't match expectations, e.g.:

	auto myFunc(Args...)(Args args) {
		struct Result {
			...
		}
		static assert(isInputRange!Result);
		return Result(args);
	}

Or similarly:

	auto myFunc(Args...)(Args args) {
		return ...;
		assert(is(typeof(return) == ExpectedType));
	}


T

-- 
The easy way is the wrong way, and the hard way is the stupid way. Pick one.


More information about the Digitalmars-d mailing list