On Mon, Nov 2, 2009 at 10:14, bearophile <bearophileHUGS@lycos.com> wrote:
Philippe Sigaud:

Hello, it seems you have re-done with ranges for D2 a good amount of things I did for D1:
http://www.fantascienza.net/leonardo/so/libs_d.zip

Ah yes, I meant to look at your libraries, but forgot to do it. I'll have a look right now, to see how you solved some problems.
 
- bimap/nmap/map: having a single map able to do all that is better. The same for filters.

Well, yes and no. It has grown organically, from the simple structs (mapping and filtering with binary functions) to the more complex ones. I have a few other ranges I want to do and then will begin the cutting down and refactoring. I coded a range segmentation as delays on a zip-range tonight (thanks Andrei for the idea!) and it seems to work. That will allow me to factor some things away.

Also, I like having generic and adaptative functions as much as the next guy, but when I tried to put every functionality inside one struct, it became some kind of godzilla of static ifs. So right now, I prefer having some specialised functions to do a more precise work, sometimes even more efficiently, that I can (theoritically) plug one into another.

And, right now, I'm limited by the fact that templates can only have one variadic type, for self-evident reasons. So you cannot have both

* map!(fun1, fun2, fun3...)(r) behavior (mapping one range with a tuple of functions)  that is, std.algo.map behavior, and,
* map!(fun, R...)(R manyRanges) (mapping one function on many ranges in parallel).

 because the ... part in the template can exist only once.
map(fun..., R ...)(R ranges) cannot exist. Well it can, but that means separating the funs from the ranges by filtering on the variadic arguments at compile time and I'm a bit leery of doing this, for not that much functionality added.

- setComprehension: better to have a set(range).

I'm afraid I disagree. I would expect set(range) to create a Set collection or to transform a range into a set (I called that asSet!R)
And anyway, I guess I'll just provide an asSet!R wrapper on one hand and comprehension on the other hand.
 
- comprehension: see select() in my dlibs.

I will and gladly, because I'd like to know how you've tackled some problems.

Right now, the comprehension range I propose can do all the computations you'll see everywhere on blogs and wikipedia:

// python
S = (2*x for x in count() if x**2 > 3)
// D
auto S = comprehension!("2*a", "a*a>3")(numbers());

But not the rebindings:
// Scala
for (p <- persons; if !p.isMale; c <- p.children) yield (c.name, p.name)

There, c comes from p.children, which is a list created anew for each p. It means that inside the for expression, p can be used to create new ranges.

Obviously, I can nest the standard comprehensions (first generating the p's, then the c's from the p and creating the tuples(p,c) from there). But I gather I can have it done internally, with a combinations of flatMap and such.


Philippe