Should the comma operator be removed in D2?

Robert Jacques sandford at jhu.edu
Tue Nov 17 14:53:55 PST 2009


On Tue, 17 Nov 2009 15:20:06 -0500, Yigal Chripun <yigal100 at gmail.com>  
wrote:

> Robert Jacques wrote:
>> On Tue, 17 Nov 2009 11:38:19 -0500, Bill Baxter <wbaxter at gmail.com>  
>> wrote:
>>
>>> On Tue, Nov 17, 2009 at 7:09 AM, Robert Jacques <sandford at jhu.edu>  
>>> wrote:
>>>> On Tue, 17 Nov 2009 05:44:31 -0500, downs <default_357-line at yahoo.de>  
>>>> wrote:
>>>>
>>>>> Robert Jacques wrote:
>>>>>>
>>>>>> On Tue, 17 Nov 2009 00:06:27 -0500, Yigal Chripun  
>>>>>> <yigal100 at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Robert Jacques wrote:
>>>>>>>>
>>>>>>>> On Mon, 16 Nov 2009 17:53:45 -0500, Stewart Gordon
>>>>>>>> <smjg_1998 at yahoo.com> wrote:
>>>>>>>>
>>>>>>>>> dsimcha wrote:
>>>>>>>>> <snip>
>>>>>>>>>>
>>>>>>>>>> Axe.  Looks like the only things it's good for are making code
>>>>>>>>>> undreadable and
>>>>>>>>>> abusing for loop syntax to...
>>>>>>>>>>  Make code unreadable.
>>>>>>>>>
>>>>>>>>> <snip>
>>>>>>>>>
>>>>>>>>> Suppose you want the increment of a for loop to change two  
>>>>>>>>> variables
>>>>>>>>> in parallel.  I don't call that making code unreadable.
>>>>>>>>>
>>>>>>>>> Stewart.
>>>>>>>>
>>>>>>>>  Yes the classic use case of the comma operator is multi-variable
>>>>>>>> declarations/increments in a for loop.
>>>>>>>
>>>>>>> This was argued before and as I and others said before, this is  
>>>>>>> *not*
>>>>>>> a use case for the comma separator.
>>>>>>>
>>>>>>> e.g.
>>>>>>> for (int a = 0, b = 1; condition(); a++, b++) {...}
>>>>>>>
>>>>>>> int a = 0, b = 1 // this is a declaration and not an expression
>>>>>>>
>>>>>>> a++, b++ // isn't assigned to any variable and can be treated as a  
>>>>>>> tuple
>>>>>>>
>>>>>>> the only use case that will break is if the two increments are
>>>>>>> dependent on the order (unless tuples are also evaluated from left  
>>>>>>> to
>>>>>>> right):
>>>>>>> e.g.
>>>>>>> a + 5, b + a //
>>>>>>>
>>>>>>> I doubt it very much that anyone ever uses this, it's too  
>>>>>>> unreadable
>>>>>>> to be useful.
>>>>>>
>>>>>> However, I imagine tuple(a++,b++) would have some overhead, which is
>>>>>> exactly what someone is trying to avoid by using custom for loops.
>>>>>>
>>>>>> Personally, I like using a..b => tuple(a,b), since it also solves  
>>>>>> the
>>>>>> multi-dimensional slicing and mixed indexing and slicing problems.
>>>>>
>>>>> Zero overhead. Tuples are flat compile-time entities.
>>>>
>>>> There are compile time tuples and runtime tuples. D already has a  
>>>> form of
>>>> compile-time tuples. This discussion seems to be about runtime tuples  
>>>> which
>>>> currently don't have a nice syntax: you have to use tuple(a,b). And
>>>> tuple(a,b) does have runtime overhead.
>>>
>>> I think the point is that in something like this:
>>>    auto foo = (a,b);
>>>    foo.a += 2;
>>>    foo.b += foo.a;
>>>    // etc
>>>
>>> The tuple foo is allocated on the stack and the compiler knows where
>>> the a part and b part are, so the code generated should be absolutely
>>> no different from the code generated for:
>>>
>>>    auto foo_a = a;
>>>    auto foo_b = b;
>>>    foo_a += 2;
>>>    foo_b += foo_a;
>>>    // etc
>>>
>>> So there doesn't need to be any "tuple overhead".
>>> --bb
>>  But that isn't the expansion:
>> for (int a = 0, b = 1; condition(); a++, b++) =>
>>  int a = 0;
>> int b = 0;
>> while(condition) {
>>     auto temp = tuple(a++,b++); // creation of a struct on the stack
>> }
>>  Now the optimizer might get rid of that temporary struct. Then again  
>> it might not (or its presence interferes with other optimizations). At  
>> the very least, some amount of code profiling or disassembly needs to  
>> be done.
>
> why would it create a struct?
>
> it would probably do:
> int a = 0, b = 0;
> while (condition) {
>    int temp_a = (a++); // temp_a == a + 1
>    int temp_b = (b++);
> }
>
> the above would most like be optimized by away.
>
> you can also take advantage of tuples with for loops, something like:
> for ( auto t = (0, 0); condition(); (t[1]++, t[2]++) ) {...}
>
> this is more flexible since you can't do with the current system:
> for (int a = 0, char b = 'a'; ; ) {...}
>
> because "int a = 0" is a declaration and not an expression.
>
> with tuples:
> for (auto t = (0, 'a'); ; ) {...}

*sigh* The reason the compiler would have to create a temporary struct, is  
because that's what a tuple is at runtime. Tuples need to be compact (like  
structs) so that they can be passed to functions, etc.



More information about the Digitalmars-d mailing list