Phobos orthogonality [Was: Re: quickSort]

bearophile bearophileHUGS at lycos.com
Wed Sep 14 04:46:37 PDT 2011


Jonathan M Davis:

> What would that gain you over passing the result of map or filter to 
> std.array.array?

1) The code gets shorter
2) The code gets a bit less noisy, because () add noise.
3) You use a single function instead of two, so you reduce the number of chunks your brain has to manage. A human brain is able to manage a very limited number of chunks at the same time (about 7). An expert programmer is able to merge array(map()) into a single chunk, but this requires a bit of training and time.
4) Maybe you are able to reduce the abstraction penalty for the compiler, reducing the amount of code compiled. (But this probably will not happen because amap will probably be just implemented with an array(map()) to reduce library code and time to write to write it).
5) The lazy result of map is quite useful. But in a large amount of situations in D you can't use a lazy result, you need an array (this is not true in Haskell). So in practice about half the time I need a map, I have to apply array() on it. So amap is a very  common pattern in D.
6) In std.parallelism there is already an map/amap pair:
http://www.d-programming-language.org/phobos/std_parallelism.html#amap
So for the D programmer it's not a significant burden to have the same functions in std.algorithm, with the same names and same purposes.

Orthogonality is overrated in Phobos. If you take a look at functional languages where the use of higher order functions is common, like Haskell, you see standard functions that are the composition of common functions. Haskell designers have a large experience on the usage of higher order functions. This is the Haskell Prelude (similar to the D object module):

http://www.haskell.org/onlinereport/standard-prelude.html

As example it contains both map and concatMap (concatMap is absent in Phobos still, but it will be useful to have). 

The definition of concatMap is just:

concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = concat . map f

In practice in Haskell you are allowed to write concatMap just like this:

concatMap = concat.map

This means concatMap is just using three functions, concat, map and dot (that is the composition function). Do you know why such simple function is included in the Prelude, despite it essentially saves just one character (the dot)? Because using a concat on the result of map is a very common pattern in Haskell code. So packing them in a single name allows the mind of the programmer to think of it as a single entity, and allows a bit higher thinking while you program.

This is why I think amap/afilter are worth adding to Phobos. I did have them in my dlibs1 and I have used them many times.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list