grauzone wrote:
Walter Bright wrote:
bearophile wrote:
grauzone:
Why did you choose to do it like this? Because it is shorter, or
for performance (avoid delegate call)?

I agree with the general points you have made. Alex has used aliases
for performance.

My dlibs (for D1) use closures, I like them. Extensive benchmarking
of mine have shown me they are often fast enough. In the spots of the
program where you need max performance I just don't use them, and I
use normal D code. The good thing is that such critical spots are
often 2-5-20% of the lines of the whole program, so for me improving
safety and syntax was a win.

It is hard to hit just the right tradeoff between performance and simplicity. One motivating issue, however, is we don't want to leave an excuse or desire to go back to C or C++ for performance reasons, even if those reasons are not reality.

But they can always roll their own versions of trivial functions like map() and so on. Isn't the point of these standard libraries to provide something simple and generic? Of course, you can't make everyone happy, but why are the performance freaks the one we need to make happy?

If you need high performance code, you'll probably always write your own, and won't trust the standard library. Just like you rewrite critical parts of code in assembler, and you don't trust the compiler.

On the other hand, I really like the string mixin approach, I think it works simply and elegantly for most predicates.

Consider you have this code:

 > map!("a*3")(a)

Now you see that you forgot something! For some reason, you actually need to return absolute values! Uh-oh, let's fix that:

 > map!("fabs(a*3)")(a)

Oops, this doesn't work. fabs() isn't available, because the code is compiled inside the standard library, and not the module, where the code was written. This is confusing and non-intuitive. Even more, you don't have _any_ way to access fabs() in this code (except if std.algorithm imports std.math). You'll have to rewrite this line of code somehow. Maybe turn it into a delegate. But then you lose the performance benefit you had before. What to do now?

map!("((a>0)?a:-a)*3")(a);

It's a good point though. Actually, I think abs(), and possibly max() and min(), should be in std.object. They're just as fundamental as division. I think that would leave sqrt() as the only function which is fast enough that the delegate overhead would be significant.
And DMD should be able to inline simple delegates anyway.


 Looks like this simple issue caused more
work than you thought! And all this even though the predicate is simple and trivial!

I don't see how this is simple and elegant. Looks more like a hack. It reminds me a bit of C++, where things first look simple, but actually... they really aren't.

But I get Don's and Andrei's points. End of discussion, I guess.

By the way: thinking about this, it always comes to my mind that D really needs AST macros!

Agreed.

Reply via email to