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