www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Function literals -- strange behavior

reply Justin <mrjnewt hotmail.com> writes:
I recently discovered D's function literals and wrote a small test to explore
them. The following code prints out a 15, then a 0. It seems to me that the
second should be 64 and not 0. Can anyone explain what I'm doing wrong?

module functionliteral;
import std.stdio;

static void main() {

	int[] values = [1,2,4,8];
	writefln(Reduce(values, function int(int x, int y) { return x + y; }));
	writefln(Reduce(values, function int(int x, int y) { return x * y; }));
}

static int Reduce(int[] values, int function(int x, int y) operation) {
	int total;
	foreach (int v; values)
		total = operation(total,v);
	return total;
}
Dec 04 2008
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Justin wrote:
 I recently discovered D's function literals and wrote a small test to explore
them. The following code prints out a 15, then a 0. It seems to me that the
second should be 64 and not 0. Can anyone explain what I'm doing wrong?
 
 module functionliteral;
 import std.stdio;
 
 static void main() {
 
 	int[] values = [1,2,4,8];
 	writefln(Reduce(values, function int(int x, int y) { return x + y; }));
 	writefln(Reduce(values, function int(int x, int y) { return x * y; }));
 }
 
 static int Reduce(int[] values, int function(int x, int y) operation) {
 	int total;
That is: total = 0 That's why in the second case it's like you are doing: 0*1*2*3*4 A reduce function normally takes the first value to use to reduce the others. So "total" would be an argument to your reduce function.
 	foreach (int v; values)
 		total = operation(total,v);
 	return total;
 }
Dec 04 2008
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Ary Borenszweig wrote:
 Justin wrote:
 I recently discovered D's function literals and wrote a small test to 
 explore them. The following code prints out a 15, then a 0. It seems 
 to me that the second should be 64 and not 0. Can anyone explain what 
 I'm doing wrong?

 module functionliteral;
 import std.stdio;

 static void main() {

     int[] values = [1,2,4,8];
     writefln(Reduce(values, function int(int x, int y) { return x + y; 
 }));
     writefln(Reduce(values, function int(int x, int y) { return x * y; 
 }));
 }

 static int Reduce(int[] values, int function(int x, int y) operation) {
     int total;
That is: total = 0 That's why in the second case it's like you are doing: 0*1*2*3*4
Well... 0*1*2*4*8
 
 A reduce function normally takes the first value to use to reduce the 
 others. So "total" would be an argument to your reduce function.
 
 
     foreach (int v; values)
         total = operation(total,v);
     return total;
 }
Dec 04 2008
parent reply Justin <mrjnewt hotmail.com> writes:
Ahh, I thought it would some stupid oversight on my part. This works:

module functionliteral;

import std.stdio;

static void main() {

	int[] values = [1,2,4,8];
	writefln(Reduce(values, function int(int x, int y) { return x + y; }));
	writefln(Reduce(values, function int(int x, int y) { return x * y; }));
}

static int Reduce(int[] values, int function(int x, int y) operation) {
	int total = values[0];
	foreach (int v; values[1..$])
		total = operation(total,v);
	return total;
}
Dec 04 2008
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 04 Dec 2008 23:08:51 +0300, Justin <mrjnewt hotmail.com> wrote:

 Ahh, I thought it would some stupid oversight on my part. This works:

 module functionliteral;

 import std.stdio;

 static void main() {

 	int[] values = [1,2,4,8];
 	writefln(Reduce(values, function int(int x, int y) { return x + y; }));
 	writefln(Reduce(values, function int(int x, int y) { return x * y; }));
 }

 static int Reduce(int[] values, int function(int x, int y) operation) {
 	int total = values[0];
 	foreach (int v; values[1..$])
 		total = operation(total,v);
 	return total;
 }
Shorter way: import std.stdio; import std.algorithm; void main() { auto values = [1,2,4,8]; writefln(reduce!("a + b")(0, values)); writefln(reduce!("a * b")(1, values)); } or import std.stdio; import std.algorithm; int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } void main() { auto values = [1, 2, 4, 8]; writefln(reduce!(add)(0, values)); writefln(reduce!(mul)(1, values)); } but the following doesn't work: import std.stdio; import std.algorithm; void main() { auto values = [1, 2, 4, 8]; writefln(reduce!((int a, int b) { return a * b; })(1, values)); } It used to work, IIRC, but now it prints '0'. Does anybody know if it is supposed to work?
Dec 04 2008
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Justin wrote:
 Ahh, I thought it would some stupid oversight on my part. This works:
 
 module functionliteral;
 
 import std.stdio;
 
 static void main() {
 
 	int[] values = [1,2,4,8];
 	writefln(Reduce(values, function int(int x, int y) { return x + y; }));
 	writefln(Reduce(values, function int(int x, int y) { return x * y; }));
 }
 
 static int Reduce(int[] values, int function(int x, int y) operation) {
 	int total = values[0];
 	foreach (int v; values[1..$])
 		total = operation(total,v);
 	return total;
 }
 
You don't need to make those static, by the way. Reduce doesn't work on all inputs: writefln(Reduce([], (int x, int y) { return x + y; }));
Dec 04 2008