Filter and Map's weird return types cause frustration...

notna notna.remove.this at ist-einmalig.de
Sat Feb 23 14:26:51 PST 2013


Thanks for this very good explanations and examples. This "Range" topic 
is a constant confusion, see one of many examples:

http://forum.dlang.org/thread/rynfksadckwinwaurtiy@forum.dlang.org

I don't understand why D cannot be simple AND efficient.
I think every function, which returns a kind of a "Range", should also 
always be able to return "char", "char[]", "char[][]", "string" and 
"string[]" per default, depending on what is expected.


On 23.02.2013 11:14, Peter Alexander wrote:
> On Saturday, 23 February 2013 at 08:48:25 UTC, Allen Nelson wrote:
>> Why are filter and map returning these weird one-off types in the
>> first place? Why would filter return anything but the same type of
>> list that it was passed as an argument? Why would map return anything
>> other than an array of whatever type matches the return value of the
>> operator? And if there's some good reason why these things are the
>> case, why then at the very least would you not be able to easily cast
>> the return type into the return type that you want?
>
> If you are using an array, you can construct an array from the result
> using std.array.array
>
> int[] evens = [1, 2, 3, 4, 5].map!(x => 2*x)().array();
>
> The reason map, filter, and most other range functions don't return the
> same type of array is because they are lazy. For example:
>
> int[] twoFourSix = [1, 2, 3, 4, 5].map!(x => 2*x)().take(3).array();
>
> Here, the mapping function is only called on the first three elements of
> the array. If map returned the array [2, 4, 6, 8, 10] then it would be
> doing more work than necessary since the take only cares about the first
> 3 elements.
>
> Also consider infinite ranges:
>
> auto twoFourSixAdInfinitum = cycle([1, 2, 3]).map!(x => 2*x)();
>
> What should map return here? You cannot have infinitely sized arrays!
>
> There's no way to have map return the same range as the input, or even
> just an array, while also being lazy. If you want an array, use
> std.array.array().
>
> Haskell manages to get around this by adding an extra layer of
> indirection around every operation, which hurts performance. D's
> standard library is designed to be high performance by default, which
> unfortunately does hurt expressiveness a little bit.



More information about the Digitalmars-d mailing list