View mode: basic / threaded / horizontal-split · Log in · Help
December 04, 2008
Function literals -- strange behavior
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
Re: Function literals -- strange behavior
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
Re: Function literals -- strange behavior
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
Re: Function literals -- strange behavior
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
Re: Function literals -- strange behavior
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
Re: Function literals -- strange behavior
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; }));
Top | Discussion index | About this forum | D home