On Wednesday, April 04, 2012 03:29:03 ixid wrote: > I understand the basic use to slice an array but what about these: > > foreach(i;0..5) > dostuff; > > That works yet this does not: > > foreach(i;parallel(0..5)) > dostuff; > > Why not let this work? It'd seem like a natural way of writing a > parallel loop. For some reason: > > foreach(i;[0,1,2,3,4]) > dostuff;
> This performs far more slowly than the first example and only as > fast as it when parallelized with a ~150ms function for each > iteration. And what would it mean in the case of parallel(0 ..5)? Notice that foreach(i; 0 .. 5) and foreach(i; [0, 1, 2. 3. 4])) mean _completely different things. The first one doesn't involve arrays it all. It gets lowered to something like for(int i = 0; i < 5; ++i) .. is _never_ used for generating an array. It's only ever used for indicating a range of values. If you want to generate a range, then use std.range.iota. .. wouldn't make sense in the contexts that you're describing. It would have to generate something. And if 0 .. 5 generated [0, 1, 2, 3, 4] in the general case, then foreach(i; ident([0 .. 5]) would be just as inefficient as foreach(i; [0, 1, 2, 3, 4, 5])) even excluding the cost of ident (which presumably just returns the array). foreach(i; 0 .. 5) is more efficient only because it has _nothing_ to do with arrays. Generalizing the syntax wouldn't help at all, and if it were generalized, it would arguably have to be consistent in all of its uses, in which case foreach(i; 0 .. 5) would become identical to foreach(i; [0, 1, 2, 3, 4]) and therefore less efficient. Generalizing .. just doesn't make sense. > One final thought- why is the array function required to convert > a lazy Result to an eager one? If you explicitly set something > like int[] blah = lazything why not have it silently convert > itself? That would be an incredibly bad idea. Converting from a lazy range to an array is expensive. You have to process the entire range and allocate memory for the array that you're stuffing it in. Sometimes, you need to do that, but you certainly don't want it to happen by accident. If such conversions were implicit, you'd get hidden performance hits all over the place if you weren't really careful. And in general, D isn't big on implicit conversions anyway. They're useful in some cases, but they often causes bugs. So, D allows a lot fewer implicit conversions than C++ does, and ranges follow that pattern. - Jonathan M Davis