April 09, 2009
Derek Parnell Wrote:

> On Wed, 08 Apr 2009 19:24:10 -0400, superdan wrote:
> 
> > ill get hands dirty n maybe report more.
> 
> If you do, can you report back using English. I'm not very good at translating your, presumably excellent, insights otherwise.

watch out. the comma police is lookin' fer ya.
April 09, 2009
One of my favorite book is Modern C++ design :thumbup:

May i ask: will the next D book have some design pattern chapters; or some 1-to-1 equivalent between C++ and D metaprogramming, to convert hardcore C++ disciple? :)

Best regards.

Andrei Alexandrescu wrote:
> Piotrek wrote:
>> Hi,
>>
>> I looked at std.algorithm. Wow, what a piece of art.
>>
>> BTW. What about your book on D? Any known dates? I know nothing about publishing business, so forgive my ignorance in advance.
>>
>> Cheers
> 
> Thanks. It's a good question. The book has 121 pages written out of the projected 350. The bottleneck is how soon we'll have a reasonably complete threading model. I don't have an exact date at the moment.
> .....
> Andrei
April 10, 2009
Thanks. I will be light on pattern specifics because I want the book to be reasonably short and focused. But metaprogramming will be an integral part of the book. In fact, I introduce a template function as soon as I introduce functions. There's no necessity to save templates for advanced chapters.

Andrei

The Anh Tran wrote:
> One of my favorite book is Modern C++ design :thumbup:
> 
> May i ask: will the next D book have some design pattern chapters; or some 1-to-1 equivalent between C++ and D metaprogramming, to convert hardcore C++ disciple? :)
> 
> Best regards.
> 
> Andrei Alexandrescu wrote:
>> Piotrek wrote:
>>> Hi,
>>>
>>> I looked at std.algorithm. Wow, what a piece of art.
>>>
>>> BTW. What about your book on D? Any known dates? I know nothing about publishing business, so forgive my ignorance in advance.
>>>
>>> Cheers
>>
>> Thanks. It's a good question. The book has 121 pages written out of the projected 350. The bottleneck is how soon we'll have a reasonably complete threading model. I don't have an exact date at the moment.
>> .....
>> Andrei
April 10, 2009
This C++0x article is relevant for comparison:

http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/
April 10, 2009
Walter Bright:
> This C++0x article is relevant for comparison: http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/

"Advanced" features have to be used only if they improve the code. I don't like that little article and the following discussion.

The following D1 code shows two ways to solve that problem with my dlibs. The first code to try is the simplest, that is to scan the data three (or even four times):

double avg = cast(double)sum(data) / len(data);
putr("min, max, avg: ", min(data), " ", max(data), " ", avg);

It works with most kind of eager/lazy numerical data, for example a lazy generator that has no length. Note that sum() is sometimes faster than a simple loop.
In many situations that code (plus some safety against division by zero) is good enough.

If you know data is huge or you have found that code to be a bottleneck, and you want a single pass you can use something like the following (code written on the fly, no unittests present, it may contain bugs):
import d.templates: IsAA, BaseType1, Record;
import d.func: putr, min, max, sum, record, len;
import d.exceptions: EmptyException;


Record!(BaseType1!(TSeq), BaseType1!(TSeq), double) minMaxAvg1(TSeq)(TSeq seq, double start=0.0) {
    auto nitems = len(seq);
    if (!nitems)
        throw new EmptyException("minMaxAvg(): 'seq' can't be empty");
    return record(min(seq), max(seq), sum(seq, start) / nitems);
}


Record!(BaseType1!(TSeq), BaseType1!(TSeq), double) minMaxAvg2(TSeq)(TSeq seq, double start=0.0) {
    BaseType1!(TSeq) dmin, dmax;
    double dtot = start;
    int nitems;

    static if (IsAA!(TSeq)) {
        foreach (el, _; seq) {
            if (nitems == 0) {
                dmin = el;
                dmax = el;
            }
            if (dmin > el) dmin = el;
            if (dmax < el) dmax = el;
            dtot += el;
            nitems++;
        }
    } else {
        foreach (el; seq) {
            if (nitems == 0) {
                dmin = el;
                dmax = el;
            }
            if (dmin > el) dmin = el;
            if (dmax < el) dmax = el;
            dtot += el;
            nitems++;
        }
    }
    if (!nitems)
        throw new EmptyException("minMaxAvg(): 'seq' can't be empty");
    return record(dmin, dmax, dtot / nitems);
}

void main() {
    int[] data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    putr("<min, max, avg>: ", minMaxAvg1(data));
    putr("<min, max, avg>: ", minMaxAvg2(data));
}

(Notice the ugly code duplication caused by the AAs).

The output:
min, max, avg: 1 10 5.5
<min, max, avg>: record(1, 10, 5.5)

Bye,
bearophile
April 10, 2009
For even bigger data you may use muds:
"On the Complexity of Processing Massive, Unordered, Distributed Data", by Jon Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, Cliff Stein, Zoya Svitkina:
http://arxiv.org/abs/cs.CC/0611108

Bye,
bearophile
April 10, 2009
bearophile wrote:
> Walter Bright:
>> This C++0x article is relevant for comparison:
>> http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/
> 
> "Advanced" features have to be used only if they improve the code. I don't like that little article and the following discussion.

Then please vote up my comment which shows a solution that is simple *and* efficient :o).

Andrei
April 10, 2009
bearophile wrote:
> For even bigger data you may use muds:
> "On the Complexity of Processing Massive, Unordered, Distributed Data", by Jon Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, Cliff Stein, Zoya Svitkina:
> http://arxiv.org/abs/cs.CC/0611108

I've developed a skepticism towards arxiv.org. My understanding is that it's not high-quality so a paper that only appears of it is highly questionable.

Andrei
April 11, 2009
Andrei Alexandrescu:

> Then please vote up my comment which shows a solution that is simple *and* efficient :o).

I am not registered there, so I can't vote, I guess.
Generally I don't like reduce() HOF, because it generally leads to less readable code (and often people use it only to compute a sum or product of items), but this time it's a good enough usage.
You have forgotten to compute the average, as requested by the original article.

Regarding field access:
assert(r.field[0] == 2); // minimum
assert(r.field[1] == 11); // maximum
I've found that sometimes a shorter syntax is nice, I use d0, d1, etc:
assert(r.d0 == 2);
assert(r.d1 == 11);
(It doesn't replace the general [] access).


>I've developed a skepticism towards arxiv.org. My understanding is that it's not high-quality so a paper that only appears of it is highly questionable.<

There some papers are very good, and some papers are ugly. I generally mostly care for the contents, so I like that source of knowledge.

Bye,
bearophile
April 11, 2009
Andrei Alexandrescu:
> Then please vote up my comment which shows a solution that is simple *and* efficient :o).

Does it work with (the keys of) an AA too? For example:
int[double] aa = [3.0:0, 4:0, 7:0, 11:0, 3:0, 2:0, 5:0];
auto r = reduce!(min, max)(aa);

Bye,
bearophile