Thread overview
Function literals -- strange behavior
Dec 04, 2008
Justin
Dec 04, 2008
Ary Borenszweig
Dec 04, 2008
Ary Borenszweig
Dec 04, 2008
Justin
Dec 04, 2008
Denis Koroskin
Dec 04, 2008
Christopher Wright
December 04, 2008
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;
}
December 04, 2008
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;
> }
December 04, 2008
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;
>> }
December 04, 2008
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;
}

December 04, 2008
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?
December 04, 2008
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; }));