More balanced orthogonality

bearophile bearophileHUGS at lycos.com
Thu Mar 17 08:54:33 PDT 2011


I've suggested to add to Phobos functions like amap(), sum(), better max()/min(), and maybe afilter() too. amap() means array(map()), sum() is similar to reduce!q{a+b}(), and the max() I have suggested is similar to reduce!max().

Notes:
- Functions like sum() are used all the time, Python programmers use it thousands of times.
- In some situations a specialized version is faster, I have shown this about sum() in an enhancement request (Andrei has then tried to generalize this suggestion of mine again);
- array(map()) uses twice the number of parentheses of amap(). Haskell syntax shows very well why too many parentheses make functional-style code needlessly harder to read.
- Experience shows me that in D you can't use lazy things as much as you use in Haskell. This means that very often I have to convert the results of D map()/filter() to true arrays.
- sum() is a semantic chunk, while reduce!q{a+b}() is not as explicit in its purpose, it's not a single chunk. You are able to speed up your coding if you need to use less chunks.
- The number of "nearly duplicated" functions to add is quite limited.

But such functions aren't orthogonal, you can build them with few other small things. In Python std library you see functions that aren't orthogonal, but they are handy, like ifilterfalse() and starmap():
http://docs.python.org/library/itertools.html

You see something similar in the Haskell Prelude (it's a standard module loaded and compiled before any other), a very well designed piece of code:
http://www.haskell.org/onlinereport/standard-prelude.html

It contains un-orthogonal functions like:

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


zipWith          :: (a->b->c) -> [a]->[b]->[c]
zipWith z (a:as) (b:bs)
                 =  z a b : zipWith z as bs
zipWith _ _ _    =  []


zip              :: [a] -> [b] -> [(a,b)]
zip              =  zipWith (,)


putStrLn   :: String -> IO ()
putStrLn s =  do putStr s
                 putStr "\n"
   

print      :: Show a => a -> IO ()
print x    =  putStrLn (show x)

Bye,
bearophile


More information about the Digitalmars-d mailing list