Thread overview
Types of lambda args
Aug 17, 2020
Cecil Ward
Aug 17, 2020
Adam D. Ruppe
Aug 17, 2020
H. S. Teoh
Aug 26, 2020
Cecil Ward
Aug 26, 2020
Paul Backus
August 17, 2020
In a lambda, how do we know what types the arguments are? In something like
    (x) => x * x

- there I just don’t get it at all. Can you write
    (uint x) => x * x

I’m lost.

Cecil Ward.
August 17, 2020
On Monday, 17 August 2020 at 00:20:24 UTC, Cecil Ward wrote:
> In a lambda, how do we know what types the arguments are? In something like
>     (x) => x * x

In that the compiler figures it out from usage context. So if you pass it to a int delegate(int), it will figure x must be int.

> - there I just don’t get it at all. Can you write
>     (uint x) => x * x

yeah you can always add more info if you like.
August 16, 2020
On 8/16/20 8:27 PM, Adam D. Ruppe wrote:
> On Monday, 17 August 2020 at 00:20:24 UTC, Cecil Ward wrote:
>> In a lambda, how do we know what types the arguments are? In something like
>>     (x) => x * x
> 
> In that the compiler figures it out from usage context. So if you pass it to a int delegate(int), it will figure x must be int.

It's actually a template, with some special benefits. It relies on IFTI to work.

-Steve
August 16, 2020
On Mon, Aug 17, 2020 at 12:20:24AM +0000, Cecil Ward via Digitalmars-d-learn wrote:
> In a lambda, how do we know what types the arguments are? In something
> like
>     (x) => x * x

It's implemented as a template, whose argument types are inferred based on usage context.


> - there I just don’t get it at all. Can you write
>     (uint x) => x * x

Of course you can.


> I’m lost.
[...]

If you're ever unsure of what the inferred type(s) are, you can do replace the lambda with something like this:

	(x) { pragma(msg, typeof(x)); return x*x }

which will print out the inferred type when the compiler instantiates the lambda.


T

-- 
Customer support: the art of getting your clients to pay for your own incompetence.
August 26, 2020
On Monday, 17 August 2020 at 04:30:08 UTC, H. S. Teoh wrote:
> On Mon, Aug 17, 2020 at 12:20:24AM +0000, Cecil Ward via Digitalmars-d-learn wrote:
>> In a lambda, how do we know what types the arguments are? In something
>> like
>>     (x) => x * x
>
> It's implemented as a template, whose argument types are inferred based on usage context.
>
>
>> - there I just don’t get it at all. Can you write
>>     (uint x) => x * x
>
> Of course you can.
>
>
>> I’m lost.
> [...]
>
> If you're ever unsure of what the inferred type(s) are, you can do replace the lambda with something like this:
>
> 	(x) { pragma(msg, typeof(x)); return x*x }
>
> which will print out the inferred type when the compiler instantiates the lambda.
>
>
> T

Ah! That’s the vital missing piece - I didn’t realise it was like a template - I just thought it was an ordinary plain anonymous function, not a generic. All makes sense now.


August 26, 2020
On Wednesday, 26 August 2020 at 15:57:37 UTC, Cecil Ward wrote:
>
> Ah! That’s the vital missing piece - I didn’t realise it was like a template - I just thought it was an ordinary plain anonymous function, not a generic. All makes sense now.

Fun fact: you can see the "de-sugared" version of many language constructs like this by looking at the compiler's AST output. For example, given a source file `lambda.d` with the following contents:

    alias fun = (x) => x*x;

The command `dmd -vcg-ast lambda.d` produces as output the file `lambda.d.cg`, with the following contents:

    import object;
    alias fun = __lambda3(__T1)(x)
    {
    	return x * x;
    }
    ;

The syntax is a little different from normal D code, but you can see the template argument `__T1` appear in addition to the function argument `x`.