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!

Reply via email to