grauzone wrote:
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? Looks like this simple issue caused more work than you thought! And all this even though the predicate is simple and trivial!

Lest a misunderstanding arises, the code:

auto r = map!((float a) { return fabs(a); })(a);

does *not* involve a delegate; it's still a direct call. This code doesn't currently compile because of a bug in the compiler, but this equivalent code does:

float fun(float a) { return fabs(a); }
auto r = map!(fun)(a);

and again it does not involve a delegate.

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.

Whereas I reckon in the beginning you weren't fully aware of the flexibility offered by pass-by-alias, you brought some good points. The functionality afforded by strings can be improved by importing more modules inside std.functional. I just added std.math and std.contracts. At the end of the day std.functional could include the entire Phobos (you'd be surprised how fast that compiles). I agree that that's not elegant, but let's not forget that strings are just that - an *additional* convenience to the many conveniences that pass-by-alias imparts.


Andrei

Reply via email to