DMD 0.170 release

Sean Kelly sean at f4.ca
Tue Oct 24 08:42:13 PDT 2006


Bruno Medeiros wrote:
> Bruno Medeiros wrote:
>> Sean Kelly wrote:
>>> Walter Bright wrote:
>>>> Oskar Linde wrote:
>>>>> One example of a generalizing addition is Tomasz' suggestion for 
>>>>> trailing delegates. It generalizes foreach, foreach_reverse and 
>>>>> even the while-loop. Such an addition would not only make libraries 
>>>>> simpler and more powerful.
>>>>
>>>> foreach_reverse is about as simple as one can get, from a user 
>>>> standpoint. It also works efficiently with arrays, which is hugely 
>>>> important because most of the time it will be used for arrays.
>>>
>>> For what it's worth, I think iterative operation requirements all 
>>> fall into one of three categories: forward, reverse, and unordered.  
>>> Forward iteration is by far the most common, so if semantic 
>>> differences are involved, it should obviously be the prettiest ;-)  
>>> Reverse iteration is not terribly common, but it does find occasional 
>>> use in search-oriented algorithms.  Unordered (for lack of a better 
>>> term) can be used to describe any operation which has no ordering 
>>> requirement and simply must be applied to all elements in a sequence.
>>>
>>> I believe it is important that the compiler be able to recognize 
>>> forward and reverse iteration at compile-time so optimizations may be 
>>> applied. After all, that's the entire point of a built-in foreach in 
>>> the first place.  Also, the compiler should be allowed to degenerate 
>>> both forward and reverse iteration to the third category, unordered, 
>>> when it can determine that visitation order has no impact on the 
>>> operations being performed.  Some criteria for this may be if the 
>>> statement block does not contain break, continue, or goto statements, 
>>> and if all operations on sequence data are commutative.  Optionally, 
>>> in instances where a statement block may not qualify for 
>>> auto-degeneration, the user should be able to specify that it should 
>>> be used anyway.  This would also allow user-defined types to 
>>> implement unordered operations in non-trivial situations.  So we have 
>>> something like this:
>>>
>>> foreach() // the default: forward iteration, compiler may degenerate
>>> foreach!(fwd)() // forward iteration, compiler may degenerate
>>> foreach!(rev)() // reverse iteration, compiler may degenerate
>>> foreach!(any)() // unordered: SSE ops may be used, concurrency, etc
>>> foreach!(fwd,strict)() // forward iteration, compiler may not degenerate
>>> foreach!(rev,strict)() // reverse iteration, compiler may not degenerate
>>> foreach!(any,strict)() // unordered, same as without strict
>>>
>>> (the above code above isn't intended to suggest syntax so much as to 
>>> describe the operations and restrictions I think may eventually be 
>>> useful)
>>>
>>> Does this sound reasonable?  And can anyone suggest a cleaner syntax?
>>>
>>>
>>> Sean
>>
>> Here's an idea:
>>
>>   foreach(foo, aggregate) {  // Unordered, so compiler may optmize
>>   foreach(foo, &aggregate.iterForward) { // Ordered and strict
>>   foreach(foo, &aggregate.iterReverse) { // Ordered and strict
>>
>> This way the strictness cannot be specified. Is it necessary? That is, 
>> is there a case where one wants an *ordered* iteration, but the 
>> compiler can optimize into an unordered (parallel) iteration? That 
>> does not seem to make sense.
>> One issue here is that one cannot specify an unordered iterator (i.e., 
>> an iterator for the case where the order does not matter), so it 
>> defaults to one only. Could there be a structure where there would be 
>> more than one meaningful unordered iterator?
> 
> Scrap that, duh. Non-ordered 'iteration' is, kinda like you said, 
> without breaks or gotos, and thus applied to all elements. So one can 
> use regular functions with delegate parameters to do this 'iteration'. 
> These non-ordered, complete 'iterations' are actually the 
> list/collection 'comprehensions' 
> (http://www.digitalmars.com/d/archives/digitalmars/D/39313.html , which 
> we knew already, but didn't remember?) which are very easy to 
> parallelize (think Google MapReduce). Doesn't this solve the issue, in 
> quite cleaner syntax and semantics?

It's a cool idea:

x = vector[ (int t){return t>5;} ]; // subset of vector
vector[] = (inout int x) { x += 100; }; // update all members of vector

However, the second example above seems like it wouldn't work for an 
array of delegates, since this is a legal 'copy' syntax.


Sean



More information about the Digitalmars-d-announce mailing list