www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Type inference for delegates/lambdas as regular parameters?

reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
(Didn't have much luck posting this on dmd-internals, so I'm posting here.)

Hi,

Consider this code:

bool contains(T)(T[] arr, scope bool delegate(T) dg)
in
{
    assert(dg);
}
body
{
    foreach (i; arr)
        if (dg(i))
            return true;

    return false;
}

import std.stdio;

void main()
{
    writeln(contains([1, 2, 3], x => x == 2));
}

This doesn't compile with 2.058; the type of x in the lambda
expression cannot be deduced. Specifying the type explicitly works
fine.

This works:

bool contains(alias dg, T)(T[] arr)
{
    foreach (i; arr)
        if (dg(i))
            return true;

    return false;
}

import std.stdio;

void main()
{
    writeln(contains!(x => x == 2)([1, 2, 3]));
}

Wasn't there supposed to be type inference for delegates passed as
regular parameters in 2.058?

Regards,
Alex

-- 
- Alex
Feb 29 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02/29/2012 05:50 PM, Alex Rønne Petersen wrote:
 (Didn't have much luck posting this on dmd-internals, so I'm posting here.)

 Hi,

 Consider this code:

 bool contains(T)(T[] arr, scope bool delegate(T) dg)
 in
 {
 assert(dg);
 }
 body
 {
 foreach (i; arr)
 if (dg(i))
 return true;

 return false;
 }

 import std.stdio;

 void main()
 {
 writeln(contains([1, 2, 3], x => x == 2));
 }

 This doesn't compile with 2.058; the type of x in the lambda
 expression cannot be deduced. Specifying the type explicitly works
 fine.

 This works:

 bool contains(alias dg, T)(T[] arr)
 {
 foreach (i; arr)
 if (dg(i))
 return true;

 return false;
 }

 import std.stdio;

 void main()
 {
 writeln(contains!(x => x == 2)([1, 2, 3]));
 }

 Wasn't there supposed to be type inference for delegates passed as
 regular parameters in 2.058?

 Regards,
 Alex

There is (try instantiating the template explicitly). The issue is that IFTI matching is performed independently on every parameter afaik.
Feb 29 2012
prev sibling next sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Wednesday, 29 February 2012 at 16:50:11 UTC, Alex Rønne 
Petersen wrote:
 (Didn't have much luck posting this on dmd-internals, so I'm 
 posting here.)

 Hi,

 Consider this code:

 bool contains(T)(T[] arr, scope bool delegate(T) dg)
 in
 {
    assert(dg);
 }
 body
 {
    foreach (i; arr)
        if (dg(i))
            return true;

    return false;
 }

 import std.stdio;

 void main()
 {
    writeln(contains([1, 2, 3], x => x == 2));
 }

 This doesn't compile with 2.058; the type of x in the lambda
 expression cannot be deduced. Specifying the type explicitly 
 works
 fine.

 This works:

 bool contains(alias dg, T)(T[] arr)
 {
    foreach (i; arr)
        if (dg(i))
            return true;

    return false;
 }

 import std.stdio;

 void main()
 {
    writeln(contains!(x => x == 2)([1, 2, 3]));
 }

 Wasn't there supposed to be type inference for delegates passed 
 as
 regular parameters in 2.058?

 Regards,
 Alex

The type inference scenario that didn't work, was supposed to be implemented, and was ultimately added for 2.058 is, Given this function: bool contains(int[] arr, scope bool delegate(int) dg); You should be able to call it like this: contains(arr, x => x == 2); // Alternatively, contains(arr, (x) { return x == 2; }); This was not previously possible, you had to make the parameter types of those delegates explicit. There is a bug that sometimes makes this inference crash even with 2.058 though, but I think it might have been fixed for the next release already (I got the same error message as one I saw in a bug report for a recently fixed bug). Now, it would be nice to have the inference you ask for as well, but I don't believe it's what was talked about. Of course, you might be referring to conversations I missed...
Feb 29 2012
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Alex R. Petersen:

 bool contains(T)(T[] arr, scope bool delegate(T) dg)
 in
 {
     assert(dg);
 }
 body
 {
     foreach (i; arr)
         if (dg(i))
             return true;
 
     return false;
 }
 
 import std.stdio;
 
 void main()
 {
     writeln(contains([1, 2, 3], x => x == 2));
 }
 
 This doesn't compile with 2.058;

dmd 2.059head fails with this reduced version, I think it's a bug for Bugzilla: int foo(T)(int delegate(T) del) { return del(1); } void main() { assert(foo((int x) => x + x)); // OK assert(foo(x => x + x)); // error } Bye, bearophile
Feb 29 2012