www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to hand in a closure variable

reply "Bienlein" <jeti789 web.de> writes:
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
Mar 24 2014
next sibling parent "Dicebot" <public dicebot.lv> writes:
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;
Mar 24 2014
prev sibling parent reply Matej Nanut <matejnanut gmail.com> writes:
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.
Mar 24 2014
parent reply "Bienlein" <jeti789 web.de> writes:
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.
Apr 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Apr 04 2014
parent reply "Bienlein" <jeti789 web.de> writes:
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.
Apr 04 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Apr 04 2014
parent "Steve Teale" <steve.teale britseyeview.com> writes:
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
Apr 07 2014
prev sibling parent reply "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
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; }}();
Apr 04 2014
parent "Bienlein" <jeti789 web.de> writes:
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; } }();
Apr 07 2014