Filter and Map's weird return types cause frustration...
Peter Alexander
peter.alexander.au at gmail.com
Sat Feb 23 02:14:17 PST 2013
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