www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5756] New: amap() and maybe afilter() too

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756

           Summary: amap() and maybe afilter() too
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



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)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 19 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756




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);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 23 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756




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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 27 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756




See also bug 5838

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 12 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756




See here for better explanations:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=29516

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 14 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5756




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);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 29 2011