Thread overview
Evaluation of expressions and the comma operator
Aug 21, 2006
Lutger
Aug 21, 2006
Lutger
August 21, 2006
I have a basic, perhaps even dumb question that came up with the awesome new implicit conversion of expressions to delegates:

In comma seperated expressions, (how) is the result of evaluation defined? For example does (a, b) always yields the value of b? I expect so, but I want to be sure.

Maybe some code is clearer, I was toying around to do this:

void main()
{
    int a = 0;
    int b = 1;
    int c = 0;

    // Prints a fibbonaci sequence, is this legal?
    writefln( generate(10, ( c = (a + b), a = b, b = c) ) );
}

T[] generate(T)(int count, T delegate() dg)
{
    T[] array;
    array.length = count;
    foreach(inout val; array)
        val = dg();
    return array;
}
August 21, 2006
Lutger wrote:
> I have a basic, perhaps even dumb question that came up with the awesome new implicit conversion of expressions to delegates:
> 
> In comma seperated expressions, (how) is the result of evaluation defined? For example does (a, b) always yields the value of b? I expect so, but I want to be sure.

Yes.  The value of a Comma is always the result of the last expression in the sequence.

> Maybe some code is clearer, I was toying around to do this:
> 
> void main()
> {
>     int a = 0;
>     int b = 1;
>     int c = 0;
> 
>     // Prints a fibbonaci sequence, is this legal?
>     writefln( generate(10, ( c = (a + b), a = b, b = c) ) );
> }
> 
> T[] generate(T)(int count, T delegate() dg)
> {
>     T[] array;
>     array.length = count;
>     foreach(inout val; array)
>         val = dg();
>     return array;
> }

I tried it myself with DMD 0.165 as:
# import std .stdio ;
#
# void main () {
#   int a = 0 ,
#       b = 1 ,
#       c = 0 ;
#
#   // prints Fibonacci sequence
#   // Note: this DOES NOT include the natural [0,1] prefix subsequence
#   writefln(generate(10, (c = (a + b), a = b, b = c)));
# }
#
# T[] generate (T) (int count, T delegate() expr) {
#   T[] result = new T[count];
#
#   foreach (inout val; result) {
#     val = expr();
#   }
#   return result;
# }

The result was a perfect compilation, and when ran it printed:
[1,2,3,5,8,13,21,34,55,89]

So it works without a hitch, except for the failure to include the [0,1] at the beginning of the Fib sequence... but that's not such a huge deal.  You can just define a
    const int[] FIB_PRE = [0, 1];

And call it as
    writefln(FIB_PRE ~ generate(10, (c = (a + b), a = b, b = c)));

-- Chris Nicholson-Sauls
August 21, 2006
Great, thank you. I agree that this line you changed looks much better: T[] result = new T[count];

Chris Nicholson-Sauls wrote:
> Lutger wrote:
>> I have a basic, perhaps even dumb question that came up with the awesome new implicit conversion of expressions to delegates:
>>
>> In comma seperated expressions, (how) is the result of evaluation defined? For example does (a, b) always yields the value of b? I expect so, but I want to be sure.
> 
> Yes.  The value of a Comma is always the result of the last expression in the sequence.
> 
>> Maybe some code is clearer, I was toying around to do this:
>>
>> void main()
>> {
>>     int a = 0;
>>     int b = 1;
>>     int c = 0;
>>
>>     // Prints a fibbonaci sequence, is this legal?
>>     writefln( generate(10, ( c = (a + b), a = b, b = c) ) );
>> }
>>
>> T[] generate(T)(int count, T delegate() dg)
>> {
>>     T[] array;
>>     array.length = count;
>>     foreach(inout val; array)
>>         val = dg();
>>     return array;
>> }
> 
> I tried it myself with DMD 0.165 as:
> # import std .stdio ;
> #
> # void main () {
> #   int a = 0 ,
> #       b = 1 ,
> #       c = 0 ;
> #
> #   // prints Fibonacci sequence
> #   // Note: this DOES NOT include the natural [0,1] prefix subsequence
> #   writefln(generate(10, (c = (a + b), a = b, b = c)));
> # }
> #
> # T[] generate (T) (int count, T delegate() expr) {
> #   T[] result = new T[count];
> #
> #   foreach (inout val; result) {
> #     val = expr();
> #   }
> #   return result;
> # }
> 
> The result was a perfect compilation, and when ran it printed:
> [1,2,3,5,8,13,21,34,55,89]
> 
> So it works without a hitch, except for the failure to include the [0,1] at the beginning of the Fib sequence... but that's not such a huge deal.  You can just define a
>     const int[] FIB_PRE = [0, 1];
> 
> And call it as
>     writefln(FIB_PRE ~ generate(10, (c = (a + b), a = b, b = c)));
> 
> -- Chris Nicholson-Sauls