Thread overview
[Issue 6714] New: Function literal does not convert to "function" and "delegate" types
[Issue 6714] [tdpl] Function literal does not convert to "function" and "delegate" types
Dec 24, 2011
Don
[Issue 6714] [tdpl] Type inference for parameters of function and delegate literals
Dec 27, 2011
Don
Dec 31, 2011
Kenji Hara
Dec 31, 2011
Walter Bright
September 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714

           Summary: Function literal does not convert to "function" and
                    "delegate" types
           Product: D
           Version: unspecified
          Platform: Other
        OS/Version: Mac OS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrei@metalanguage.com


--- Comment #0 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-09-22 07:31:43 PDT ---
Consider:


void foo (int function (int, int) a){}
void bar (int delegate (int, int) a){}

void main ()
{
    foo((a, b) { return a +b;});
    bar((a, b) { return a +b;});
}

Neither call works. The literal does not convert to the function or the delegate type.

Additionally (this might have been reported), a function type should convert automatically to a delegate type with the same arguments and return type. Walter has expressed doubts about that. The doubts are unfounded.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 19, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714


Andrei Alexandrescu <andrei@metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Function literal does not   |[tdpl] Function literal
                   |convert to "function" and   |does not convert to
                   |"delegate" types            |"function" and "delegate"
                   |                            |types


--- Comment #1 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-12-18 20:06:05 PST ---
Related to http://d.puremagic.com/issues/show_bug.cgi?id=3235

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 24, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #2 from Don <clugdbug@yahoo.com.au> 2011-12-24 04:23:32 PST ---
(In reply to comment #0)
> Consider:
> 
> 
> void foo (int function (int, int) a){}
> void bar (int delegate (int, int) a){}
> 
> void main ()
> {
>     foo((a, b) { return a +b;});
>     bar((a, b) { return a +b;});
> }
> 
> Neither call works. The literal does not convert to the function or the delegate type.

This works though:
     bar((int a, int b) { return a + b;});
Is that what you meant? If it is, then this is a duplicate of 3235.

Or are argument types supposed to be deduced? If so, that's a major, complicated feature and difficult to implement, I think it requires an extra level of argument matching. It would need to be considered very carefully. Eg, which of these calls are ambiguous?

void bar ( double delegate(int, int) a ) {}
void bar ( int delegate (int, int) a ){}

bar( (a, b) { return 1.0; } );
bar( (a, b) { return 1.0f; } );
bar( (a, b) { return a; } );

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 24, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714



--- Comment #3 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-12-24 09:32:58 PST ---
(In reply to comment #2)
> (In reply to comment #0)
> > Consider:
> > 
> > 
> > void foo (int function (int, int) a){}
> > void bar (int delegate (int, int) a){}
> > 
> > void main ()
> > {
> >     foo((a, b) { return a +b;});
> >     bar((a, b) { return a +b;});
> > }
> > 
> > Neither call works. The literal does not convert to the function or the delegate type.
> 
> This works though:
>      bar((int a, int b) { return a + b;});
> Is that what you meant? If it is, then this is a duplicate of 3235.
> 
> Or are argument types supposed to be deduced? If so, that's a major, complicated feature and difficult to implement, I think it requires an extra level of argument matching.

When I discussed with Walter the matter a while ago, a possible approach was that the literal relying on deduction defines a local template function. For example, the code:

    foo((a, b) { return a +b;});

would be lowered into:

    static auto __lambda(T1, T2)(T1 a, T2 b) { return a + b; }
    foo(__lambda);

The "static" is present because the compiler figured the lambda uses no state from the enclosing context. Built-in conversion mechanisms should take over from here on.

This also brings the issue of automatically converting a function to a delegate. Walter disagrees with that, but I disagree with the basis of his disagreement.

> It would need to be considered very carefully.
> Eg, which of these calls are ambiguous?
> 
> void bar ( double delegate(int, int) a ) {}
> void bar ( int delegate (int, int) a ){}
> 
> bar( (a, b) { return 1.0; } );

Works, goes to first overload.

> bar( (a, b) { return 1.0f; } );

Doesn't work, no conversion possible for either overload.

> bar( (a, b) { return a; } );

Depends on a's type.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 27, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid, spec
            Version|unspecified                 |D2
            Summary|[tdpl] Function literal     |[tdpl] Type inference for
                   |does not convert to         |parameters of function and
                   |"function" and "delegate"   |delegate literals
                   |types                       |
         OS/Version|Mac OS X                    |All
           Severity|normal                      |enhancement


--- Comment #4 from Don <clugdbug@yahoo.com.au> 2011-12-26 17:10:36 PST ---
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #0)
> > > Consider:
> > > 
> > > 
> > > void foo (int function (int, int) a){}
> > > void bar (int delegate (int, int) a){}
> > > 
> > > void main ()
> > > {
> > >     foo((a, b) { return a +b;});
> > >     bar((a, b) { return a +b;});
> > > }
> > Are argument types supposed to be deduced? If so, that's a major, complicated feature and difficult to implement, I think it requires an extra level of argument matching.
> 
> When I discussed with Walter the matter a while ago, a possible approach was that the literal relying on deduction defines a local template function.

Changing bug title from the original ´Function literal does not convert to "function" and "delegate" types´, since this seems to be type inference enhancement, which requires a spec change.

> For example, the code:
> 
>     foo((a, b) { return a +b;});
> 
> would be lowered into:
> 
>     static auto __lambda(T1, T2)(T1 a, T2 b) { return a + b; }
>     foo(__lambda);
> 
> The "static" is present because the compiler figured the lambda uses no state from the enclosing context. Built-in conversion mechanisms should take over from here on.

I don't understand how this works. Where does the template get instantiated?

In the examples at the end of comment 3, it seems to be deducing the parameters
of __lambda from parameters of foo. This seems very complicated.
If foo is a template function, in every existing situation, all the types of
the arguments are known. Here, they aren't. For example if foo is:

void foo(T = int, R)( R function(T, T) f)

then we'd expect T1, T2 to be deduced as int (because of the default value of
T). We now have enough information to instantiate __lambda, which then allows
us to determine R. We can then finally instantiate foo. We're instantiating two
templates at once, and they're kind of interlocked. The interlocking continues
further: if the parameter deduction or template constraint of foo fails, then
the instantiation of __lambda must also be discarded.
The 4-step template argument deduction process described in template.html is
gone.

> This also brings the issue of automatically converting a function to a delegate. Walter disagrees with that, but I disagree with the basis of his disagreement.

Obviously this needs to be resolved.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 31, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> 2011-12-30 21:23:58 PST ---
https://github.com/D-Programming-Language/dmd/pull/588

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 31, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6714


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |FIXED


--- Comment #6 from Walter Bright <bugzilla@digitalmars.com> 2011-12-31 12:24:37 PST ---
https://github.com/D-Programming-Language/dmd/commit/c50eb5f5726a65efa1224ff0f0fd60acbb6e3027

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------