[Issue 4705] New: Redesign of std.algorithm.max()/min() + mins()/maxs()

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Aug 21 11:14:04 PDT 2010


http://d.puremagic.com/issues/show_bug.cgi?id=4705

           Summary: Redesign of std.algorithm.max()/min() + mins()/maxs()
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: bearophile_hugs at eml.cc


--- Comment #0 from bearophile_hugs at eml.cc 2010-08-21 11:14:01 PDT ---
Here I propose a redesign of the std.algorithm.max()/min() functions, and the
creation of two related functions, that may be named mins()/maxs().

Usually the contents of std.algorithm.max() are not necessary to program in D2,
their main purpose is to allow to shorten programs (and avoid some bugs),
especially in the large number of situations where maximum performance is not
necessary.

So the contents of std.algorithm must be flexible and handy to use. So the
contents of this module need to be chosen according to the most common pattern
found in normal programs. To show few examples I use Python code (because
Python design shows a very good choice of the most common patterns you find in
your code).


The task is to collect all items that have the max length:

>>> maxlen = max(len(item) for item in data)
>>> [item for item in data if len(item) == maxlen]
['hello', 'roger']


This task is so common that I use an utility module (as you see in Python max()
accepts an optional key mapping function):

>>> from util import maxs
>>> maxs(data, key=len)
['hello', 'roger']


A subtask is to find the length of the longer string of 'data', here I show two
possible solutions:

>>> data = ["red", "hello", "yes", "no", "roger", "bud"]
>>> len(max(data, key=len))
5
>>> max(len(item) for item in data)
5


This code shows a possible D2 solution of the subtask and task:

import std.stdio: writeln;
import std.algorithm: reduce, map, filter, max;
import std.range: walkLength;
void main() {
    string[] data = ["red", "hello", "yes", "no", "roger", "bud"];
    int lmax = reduce!max(map!walkLength(data));
    writeln(lmax);
    auto maxs = filter!((a){ return a.length == lmax; })(data);
    writeln(maxs);
}


But "reduce!max(map!walkLength(data))" is too much complex for such simple and
common task (I have found that code only after many tries), so I think the
current max() design is not good enough.

My experience shows that the most common&handy usages of max()/min() are four
(for each):

max(item1, item2)
max(item1, item2, item3)
max(collection)
max!(callable)(collection)

min(item1, item2)
min(item1, item2, item3)
min(collection)
min!(callable)(collection)

They are: to find the max among two items, among tree items, among a collection
of items, and among a collection of items using a mapping callable.

The callable is similar to the 'transform' function of schwartzSort().

So I suggest a redesign of min() and max() according to those four most common
usages.

I also suggest to create two new functions, that I have just called maxs() and
mins() similar to max and min, that find all the max or min items of a given
collection. They don't need the case with two or three items:

maxs(collection)
maxs!(callable)(collection)

mins(collection)
mins!(callable)(collection)


(If this proposal gets accepted I may be able to create a patch with this
changes to max/min and the mins/maxs. I have written the same four functions
for D1, that don't use ranges.)

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


More information about the Digitalmars-d-bugs mailing list