www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Function Literals

reply Falk Henrich <schreibmalwieder hammerfort.de> writes:
Hi!

I'm just experimenting with delegates and came across

http://www.digitalmars.com/d/expression.html#FunctionLiteral

where one finds this example:

int abc(int delegate(long i));
void test()
{   int b = 3;
    abc( (long c) { return 6 + b; } );
}

My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.

Is it possible to simulate a syntax like

abc( (c) { return 6+b; } );

using templates / mixins?

Thanks for the advice!

Falk
Mar 13 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Falk Henrich wrote:
 Hi!
 
 I'm just experimenting with delegates and came across
 
 http://www.digitalmars.com/d/expression.html#FunctionLiteral
 
 where one finds this example:
 
 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }
 
 My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.
 
 Is it possible to simulate a syntax like
 
 abc( (c) { return 6+b; } );
 
 using templates / mixins?
 
 Thanks for the advice!
 
 Falk

This is purely speculation, however: All the type inference that D does thus far seems to be "inside-out", that is it uses the known type of inner expressions to determine the type of the ones they're contained in. Deriving the type of 'c' up there would mean the system would have to work backwards; and things could get messy :P Secondly, (c) looks like a C-style cast, and D doesn't like C-style casts. In fact, last time I checked, it spat the dummy if you use a C-style cast. Thirdly, it could be that it's possible, but an awful lot of work, and Walter doesn't see that it's worth it. Given that we recently got compile-time function evaluation, I'd agree with him :) You also ask if it's possible to simulate the syntax using templates/mixins. I'd dare say it would be, but it would probably end up being far more typing than it's worth:
 abc( mixin(infer(&abc, "(c) { return 6+b; }")) );

As an example, compared to
 abc( (long c) { return 6+b; } );

-- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Mar 13 2007
next sibling parent reply janderson <askme me.com> writes:
Daniel Keep wrote:
 
 Falk Henrich wrote:
 Hi!

 I'm just experimenting with delegates and came across

 http://www.digitalmars.com/d/expression.html#FunctionLiteral

 where one finds this example:

 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }

 My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.

 Is it possible to simulate a syntax like

 abc( (c) { return 6+b; } );

 using templates / mixins?

 Thanks for the advice!

 Falk

This is purely speculation, however: All the type inference that D does thus far seems to be "inside-out", that is it uses the known type of inner expressions to determine the type of the ones they're contained in. Deriving the type of 'c' up there would mean the system would have to work backwards; and things could get messy :P

I'm not familiar with the compiler, so I'll just have to believe thats true.
 
 Secondly, (c) looks like a C-style cast, and D doesn't like C-style
 casts.  In fact, last time I checked, it spat the dummy if you use a
 C-style cast.

While the other points seem valid. A syntax change to: abc( (auto c) { return 6+b; } ); could be about as useful without it looking like a C-style cast.
 
 Thirdly, it could be that it's possible, but an awful lot of work, and
 Walter doesn't see that it's worth it.  Given that we recently got
 compile-time function evaluation, I'd agree with him :)
 
 You also ask if it's possible to simulate the syntax using
 templates/mixins.  I'd dare say it would be, but it would probably end
 up being far more typing than it's worth:
 
 abc( mixin(infer(&abc, "(c) { return 6+b; }")) );

As an example, compared to
 abc( (long c) { return 6+b; } );


Very true. Although depending on the problem sometimes it can be re-designed to use templates instead of delegates.
 	-- Daniel
 

Mar 13 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
janderson wrote:
 Daniel Keep wrote:
 All the type inference that D does thus far seems to be "inside-out",
 that is it uses the known type of inner expressions to determine the
 type of the ones they're contained in.  Deriving the type of 'c' up
 there would mean the system would have to work backwards; and things
 could get messy :P

I'm not familiar with the compiler, so I'll just have to believe thats true.

'Well, I suppose it makes sen--' Vimes began. 'That isn't how it works at all, Lu-Tze!' wailed Qu. 'No,' said Sweeper, 'but it's another good lie.' -- Terry Pratchett, "Night Watch". :3 -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Mar 13 2007
parent janderson <askme me.com> writes:
Daniel Keep wrote:
 
 janderson wrote:
 Daniel Keep wrote:
 All the type inference that D does thus far seems to be "inside-out",
 that is it uses the known type of inner expressions to determine the
 type of the ones they're contained in.  Deriving the type of 'c' up
 there would mean the system would have to work backwards; and things
 could get messy :P

true.

'Well, I suppose it makes sen--' Vimes began. 'That isn't how it works at all, Lu-Tze!' wailed Qu. 'No,' said Sweeper, 'but it's another good lie.' -- Terry Pratchett, "Night Watch". :3

Aha, good old, Terry Pratchett. My favorite non-technical author :) -Joel
Mar 14 2007
prev sibling parent Falk Henrich <schreibmalwieder hammerfort.de> writes:
Daniel Keep wrote:

 All the type inference that D does thus far seems to be "inside-out",
 that is it uses the known type of inner expressions to determine the
 type of the ones they're contained in.  Deriving the type of 'c' up
 there would mean the system would have to work backwards; and things
 could get messy :P

I understand.
 
 Secondly, (c) looks like a C-style cast, and D doesn't like C-style
 casts.  In fact, last time I checked, it spat the dummy if you use a
 C-style cast.

You are right, I didn't think about casts when making up the example.
 Thirdly, it could be that it's possible, but an awful lot of work, and
 Walter doesn't see that it's worth it.  Given that we recently got
 compile-time function evaluation, I'd agree with him :)

As I understand, the concepts of anonymous delegates / functions are special cases of lambda expressions. Digging through the news archives I get the impression that D is moving towards general lambdas on a step-by-step basis. Under this assumption, I came to the question concerning the automatic type inference. Anyway, I think D's pragmatic combination of high-level functional features with performance critical elements is very nice. Falk
Mar 14 2007
prev sibling next sibling parent reply Russell Lewis <webmaster villagersonline.com> writes:
abc() could be overloaded.

Falk Henrich wrote:
 Hi!
 
 I'm just experimenting with delegates and came across
 
 http://www.digitalmars.com/d/expression.html#FunctionLiteral
 
 where one finds this example:
 
 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }
 
 My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.
 
 Is it possible to simulate a syntax like
 
 abc( (c) { return 6+b; } );
 
 using templates / mixins?
 
 Thanks for the advice!
 
 Falk
 

Mar 14 2007
parent BCS <ao pathlink.com> writes:
Reply to Russell,

 abc() could be overloaded.
 

that hasn't stopped things before. <g> void fn(int); void fn(float); void foo(void function(int)); void foo(void function(float)); foo(&fn); // this works (badly)
Mar 14 2007
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Falk Henrich wrote:
 Hi!
 
 I'm just experimenting with delegates and came across
 
 http://www.digitalmars.com/d/expression.html#FunctionLiteral
 
 where one finds this example:
 
 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }
 
 My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.

The problem is it doesn't know the function signature of abc, since abc may be overloaded, and may even be a function template.
Mar 14 2007
next sibling parent Reiner Pope <no spam.com> writes:
Walter Bright Wrote:

 Falk Henrich wrote:
 Hi!
 
 I'm just experimenting with delegates and came across
 
 http://www.digitalmars.com/d/expression.html#FunctionLiteral
 
 where one finds this example:
 
 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }
 
 My question is: If the compiler can infer the return type of the anonymous
function, how come it can't infer the type of the parameter c? Forgive me if
this is too stupid a question, but I thought: if the compiler knows the
signature of abc it has to be clear that c is of type long.

The problem is it doesn't know the function signature of abc, since abc may be overloaded, and may even be a function template.

We already effectively have type inference on parameters for function literals: the foreach statement. Cheers, Reiner
Mar 14 2007
prev sibling parent Falk Henrich <schreibmalwieder hammerfort.de> writes:
Walter Bright wrote:

 Falk Henrich wrote:
 int abc(int delegate(long i));
 void test()
 {   int b = 3;
     abc( (long c) { return 6 + b; } );
 }
 
 My question is: If the compiler can infer the return type of the
 anonymous function, how come it can't infer the type of the parameter c?
 Forgive me if this is too stupid a question, but I thought: if the
 compiler knows the signature of abc it has to be clear that c is of type
 long.

The problem is it doesn't know the function signature of abc, since abc may be overloaded, and may even be a function template.

The D compiler and I agree with you that given a situation like this: int abc(int delegate(int) f) {return f(1);} int abc(int delegate(real) f) {return f(0);} int test() { return abc( (real c) { if (c >= 0) return +1; else return -1; } ); } some kind of type annotation is needed. But this leads me to two related (newbie-type) questions: 1.) Would it be possible to make the type annotation optional, so the compiler throws an error if it gets confused and accepts the code if there is no ambiguity? 2.) Does the D compiler consider return types at all? The code int huhu() { return 5; } double huhu() { return 5; } leads to a conflict (like usual in C, C++, and Java). Therefore, I suspect, it doesn't. Maybe I missed something obvious again... Falk
Mar 14 2007