Thread overview
How to hand in a closure variable
Mar 24, 2014
Bienlein
Mar 24, 2014
Dicebot
Mar 24, 2014
Matej Nanut
Apr 04, 2014
Bienlein
Apr 04, 2014
bearophile
Apr 04, 2014
Bienlein
Apr 04, 2014
bearophile
Apr 07, 2014
Steve Teale
Apr 04, 2014
Jesse Phillips
Apr 07, 2014
Bienlein
March 24, 2014
Hello,

I have some piece of code that compiles and runs fine:

void main(string[] args)
{	
	int a = 7;
	int delegate() dg = { return a + 3; };
	auto result = dg();
	writeln(result);
}

Now I want the closure (aka delegate) to have a closure variable:

int a = 7;
int delegate(int) dg = { value => return value + a + 3; };
auto result = dg(123);

Unhappily, the code above doesn't compile. Tried various things, looked for samples on the D hompepage and in the book by Çehreli, but had no luck.

Some hints appreciated.
Thanks, Bienlein
March 24, 2014
On Monday, 24 March 2014 at 16:40:55 UTC, Bienlein wrote:
> Now I want the closure (aka delegate) to have a closure variable:
>
> int a = 7;
> int delegate(int) dg = { value => return value + a + 3; };
> auto result = dg(123);
>
> Unhappily, the code above doesn't compile. Tried various things, looked for samples on the D hompepage and in the book by Çehreli, but had no luck.
>
> Some hints appreciated.
> Thanks, Bienlein

auto dg = (int value) { return value + a + 3; };

or short-hand form:

auto dg = (int value) => value + a + 3;
March 24, 2014
Hello!

You just missed the syntax a little.

Instead of:

> int delegate(int) dg = { value => return value + a + 3; };

You can write

    auto dg = (int value) { return value + a + 3; }; // Omitted return
type, but had to specify type of value.

or

    auto dg = (int value) => value + a + 3; // Notice no "return" keyword.

or

    int delegate(int) dg = value => value + a + 3; // Omitted type of
value, but had to write the full type of dg.

You can also write a delegate as an inner function:

    int a = 7;
    int dg(int value)
    {
        return value + a + 3;
    }
    auto result = dg(123);

I'm not sure, but I guess all of these should mean the same thing.
April 04, 2014
Thanks so far. I have another one, though. Not trying to tease people, I really don't know ;-).

This compiles and runs:

immutable int a = (int val) {
	if(1 == 1) {
		return val;
	} else {
		return 456;
	}
}(123);	
	
writeln(a);

Whereas this does not compile:

immutable int b = (int) {
	if(1 == 1) {
		return 123;
	} else {
		return 456;
	}
}(); // line x	

However, this does compile and displays correctly 123:

immutable int b = (int) {
	if(1 == 1) {
		return 123;
	} else {
		return 456;
	}
}(1); // line y	
		
writeln(b);

Note it says () in line x and (1) in line y. The (1) in line y is redundant, but the stuff then compiles.
April 04, 2014
Bienlein:

> Whereas this does not compile:
>
> immutable int b = (int) {
> 	if(1 == 1) {
> 		return 123;
> 	} else {
> 		return 456;
> 	}
> }(); // line x	
>
> However, this does compile and displays correctly 123:
>
> immutable int b = (int) {
> 	if(1 == 1) {
> 		return 123;
> 	} else {
> 		return 456;
> 	}
> }(1); // line y	
> 		
> writeln(b);
>
> Note it says () in line x and (1) in line y. The (1) in line y is redundant, but the stuff then compiles.

If your D function has one argument, you have to give it one argument, even if it doesn't have a visible name and it's unused.

Bye,
bearophile
April 04, 2014
On Friday, 4 April 2014 at 13:53:33 UTC, bearophile wrote:

> If your D function has one argument, you have to give it one argument, even if it doesn't have a visible name and it's unused.

Ah! Admittedly, I though it's the return type .. So this works
now:

immutable int b = () {
	if(1 == 1) {
		return 123;
	} else {
		return 456;
	}
}();

What I was actually looking for was how to get this to work:

immutable int b = if(1 == 1) { return 123; } else { return 456; };

But I'm happy enough with the solution through a delegate.
April 04, 2014
Bienlein:

> What I was actually looking for was how to get this to work:
>
> immutable int b = if(1 == 1) { return 123; } else { return 456; };

immutable b = (1 == 1) ? 123 : 456;

Bye,
bearophile
April 04, 2014
On Friday, 4 April 2014 at 15:13:25 UTC, Bienlein wrote:
> What I was actually looking for was how to get this to work:
>
> immutable int b = if(1 == 1) { return 123; } else { return 456; };
>
> But I'm happy enough with the solution through a delegate.

What bearophile said, or:

immutable int b = {if(1 == 1) { return 123; } else { return 456; }}();
April 07, 2014
On Friday, 4 April 2014 at 19:56:14 UTC, Jesse Phillips wrote:
> On Friday, 4 April 2014 at 15:13:25 UTC, Bienlein wrote:
>> What I was actually looking for was how to get this to work:
>>
>> immutable int b = if(1 == 1) { return 123; } else { return 456; };
>>
>> But I'm happy enough with the solution through a delegate.
>
> What bearophile said, or:
>
> immutable int b = {if(1 == 1) { return 123; } else { return 456; }}();

Thanks, that's it! Now I can also do what I initialliy wanted to (e.g. have several lines of code in the expression blocks):

immutable int b = {
    if(1 == 1) {
        writeln("123");
        return 123;
    } else {
        writeln("456");
        return 456;
    }
}();
April 07, 2014
On Friday, 4 April 2014 at 15:15:55 UTC, bearophile wrote:
> Bienlein:
>
>> What I was actually looking for was how to get this to work:
>>
>> immutable int b = if(1 == 1) { return 123; } else { return 456; };
>
> immutable b = (1 == 1) ? 123 : 456;
>
> Bye,
> bearophile

You said you did not like ternary expressions ;=)

Steve