Bug 5756 – amap() and maybe afilter() too

Status
NEW
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-03-19T17:09:37Z
Last change time
2024-12-01T16:14:01Z
Keywords
bootcamp
Assigned to
No Owner
Creator
bearophile_hugs
Moved to GitHub: phobos#9900 →

Comments

Comment #0 by bearophile_hugs — 2011-03-19T17:09:37Z
I suggest to add to Phobos functions like amap() and maybe afilter() too. amap() means array(map()) afilter() means array(filter()) Rationale: - 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)
Comment #1 by bearophile_hugs — 2011-03-23T23:47:04Z
As in std.parallelism, I suggest to add a second optional argument to the amap()/afilter(), an optional buffer to return the result. If the buffer is provided, it must be the same length as the range. So you write: auto numbers = iota(10); auto squareRoots = new double[numbers.length]; amap!sqrt(numbers, squareRoots); Instead of: auto numbers = iota(10); auto squareRoots = new double[numbers.length]; copy(map!sqrt(numbers), squareRoots);
Comment #2 by bearophile_hugs — 2011-03-27T13:38:59Z
It seems dsimcha has renamed two functions in std.parallelism, now the eager version is named amap: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=132731
Comment #3 by bearophile_hugs — 2011-04-12T17:19:56Z
See also bug 5838
Comment #4 by bearophile_hugs — 2011-09-14T04:55:40Z
Comment #5 by bearophile_hugs — 2011-09-29T15:06:38Z
An example of amap usage. This is input data: auto data = ["1111100000", "1111000000", "1110000000", "1100001000", "1000010000", "0000100001", "0001000011", "0010000111", "0000001111", "0000011111"]; To convert it into a 2D matrix of booleans: auto r = array(map!q{ array(map!q{ a == '1' }(a)) }(data)); The result r: [[true, true, true, true, true, false, false, false, false, false], [true, true, true, ...]] Using amap the line of code becomes shorter and less noisy, almost readable: auto r = amap!q{ amap!q{ a == '1' }(a) }(data);
Comment #6 by lt.infiltrator — 2014-03-19T21:21:18Z
Would you like to create a PR for this?
Comment #7 by robert.schadek — 2024-12-01T16:14:01Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9900 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB