Common scope for function's in{}, out(result){} and body{}

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 12 14:31:20 PDT 2014


On Fri, Sep 12, 2014 at 06:41:29AM +0000, Ilya Yaroshenko via Digitalmars-d wrote:
> Hello!
> 
> There are local imports available in D.
> But if contract programming is necessary there are no common function
> scope.
> 
> So I suppose D need common scope:
> 
> -----------------------------------
> auto functionName(Range1, Range2)(Range1 r1, Ranger2)
> scope  {
>     import std.range; //imports are allowed
>     enum MaxLength = 1024; //enums are allowed
>     immutable A = [0.123, 0.456, 0.789]; // immutable and const are allowed
>     bool isOdd (uint i) {return i%2;}
> 
>     static assert(isInputRange!Range1,
>         Range1.stringof!~" is not InputRange");
> 
> 
>     int i; //Error, mutable data disallowed.
>     immutable length = r1.length; //Error, can't use function parameters.
> 
> 
> }
> in {
>    assert(!r1.empty); // we already know that r1 is InputRange and function
> have local imports!
> 
>  // can use std.range, MaxLength, A, isOdd
> }
> out(result) {
>  // can use std.range, MaxLength, A, isOdd
> }
> body {
>  // can use std.range, MaxLength, A, isOdd
> }
> -------------------------------
> 
> 
> What do you think?
[...]

Actually, there *is* already a function-wide scope that includes
contracts and signature constraints. Remember that when you write:

	auto functionName(A...)(A args) { ... }

it's actually a shorthand for:

	template functionName(A...)
	{
		auto functionName(A args) { ... }
	}

This is known as an "eponymous template", which is a nice syntactic
shorthand where if the template member has the same name as the
template, then you don't have to write:

	functionName!(...).functionName(...)

but it can be collapsed into just:

	functionName!(...)(...)

So, to achieve what you want, you'd simply write:

	template functionName(Range1, Range2)
	{
		import std.range;
		enum MaxLength = 1024;
		immutable A = [0.123, 0.456, 0.789];
		bool isOdd(uint i) { return i%2; }

		static assert(isInputRange!Range1, ...);

		auto functionName(Range1 r1, Range2 r2)
		in {
			assert(!r1.empty);
			// can use std.range, MaxLength, A, isOdd
		}
		out(result) {
			// can use std.range, MaxLength, A, isOdd
		}
		body
		{
			// can use std.range, MaxLength, A, isOdd
		}
	}


T

-- 
That's not a bug; that's a feature!


More information about the Digitalmars-d mailing list