www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Partial return type specification

reply bearophile <bearophileHUGS lycos.com> writes:
This post is probably silly, so feel free to ignore it :-)

As function return type I am able to use the correct type, as in the bar()
function below, or 'auto' that's a Jolly that works for any type, and is useful
when the type is very complex:


import std.algorithm: map, equal;

/* Range!int */ auto foo() {
    return map!("a * a")([1, 2, 3, 4]);
}

/* Range!int */ int[] bar() {
    return [1, 2, 3, 4];
}

void main() {
    assert(equal(foo(), [1, 4, 9, 16]));
    assert(equal(bar(), [1, 2, 3, 4]));
}


But in some situations I've felt the need of something intermediate, like a way
to say that the output of the function is an iterable of int values (instead of
strings or floats), like a Range!int.

Even using this annotation, the actual return type of the function foo()
doesn't change, it's still a map!(), so the Range!int acts just like the
generic "auto", the difference is that the compiler gives a compile error if
the result isn't an iterable of ints.

So I am talking about something like (this doesn't compile because I think you
can't use 'auto' with functions with a out() contract):


import std.algorithm: map, equal;
import std.traits: ForeachType, Unqual;

auto foo()
    out(result) {
        static assert(is(Unqual!(ForeachType!(typeof(result))) == int));
    }
    body {
        return map!("a * a")([1, 2, 3, 4]);
    }

void main() {
    assert(equal(foo(), [1, 4, 9, 16]));
}


Bye,
bearophile
Oct 03 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
 But in some situations I've felt the need of something intermediate, like a
way to say that the output of the function is an iterable of int values
(instead of strings or floats), like a Range!int.

That's just a static iterable interface, I guess. It was discussed here in past. Bye, bearophile
Oct 03 2010
prev sibling parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
Maybe typeof(return) is what you're looking for? *

auto foo()
{
    return map!("a * a")([1, 2, 3, 4]);
    static assert(is(Unqual!(ForeachType!(typeof(return))) == int));
}

* Not tested, I don't know if it works like this at all. 
Oct 03 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Daniel Murphy:

 Maybe typeof(return) is what you're looking for? *
 
 auto foo()
 {
     return map!("a * a")([1, 2, 3, 4]);
     static assert(is(Unqual!(ForeachType!(typeof(return))) == int));
 }
 
 * Not tested, I don't know if it works like this at all.

That works, thank you. Yes, I am looking for syntax sugar for that code. Bye, bearophile
Oct 04 2010
parent reply Pelle <pelle.mansson gmail.com> writes:
On 10/04/2010 01:33 PM, bearophile wrote:
 Daniel Murphy:

 Maybe typeof(return) is what you're looking for? *

 auto foo()
 {
      return map!("a * a")([1, 2, 3, 4]);
      static assert(is(Unqual!(ForeachType!(typeof(return))) == int));
 }

 * Not tested, I don't know if it works like this at all.

That works, thank you. Yes, I am looking for syntax sugar for that code. Bye, bearophile

You can hack it with a string mixin :-) string assertReturnsRangeOf(T)() { return "static assert (is(Unqual!(ForeachType!(typeof(return))) == " ~ T.stringof ~ "));"; } auto foo() { return map!q{a*a}([1,2,3,4,5]); mixin (assertReturnsRangeOf!int); } You were probably looking for a more general and, well, good, solution. This does however convey some intent, and kind of works.
Oct 04 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Pelle:

 You were probably looking for a more general and, well, good, solution. 
 This does however convey some intent, and kind of works.

Your solution looks cute enough, I may even try to use it. But a template seems better than a function template (because eventually functions are supposed to require the () to be called): import std.algorithm: map, equal; import std.traits: ForeachType, Unqual; template AssertReturnsRangeOf(T) { enum string AssertReturnsRangeOf = "static assert (is(Unqual!(ForeachType!(typeof(return))) == " ~ T.stringof ~ "));"; } auto foo() { return map!q{a*a}([1,2,3,4]); mixin(AssertReturnsRangeOf!int); } void main() { assert(equal(foo(), [1, 4, 9, 16])); } Bye, bearophile
Oct 04 2010