Ary Borenszweig escribió:
Andrei Alexandrescu escribió:
Ary Borenszweig wrote:
Andrei Alexandrescu escribió:
I've updated my code and documentation to include series (as in
math) in the form of infinite ranges. Also series in closed form
(given n can compute the nth value without iterating) are supported
as random-access ranges.
Also Stride is provided. The Matrix container (speaking of
scientific computing with D!) will support various representational
choices, most importantly the ones endorsed by high-performance
libraries. For Matrix, Stride is an important component as I'm sure
anyone who's ever written a matrix knows.
http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_range.html
http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_algorithm.html
Back to series. Finally my dream has come true: I can define a
decent Fibonacci series clearly and efficiently in one line of code.
No more idiotic recursive function that takes exponential time to
finish!
auto fib = series!("a[n-1] + a[n]")(1, 1);
// write 10 Fibonacci numbers
foreach (e; take(10, fib)) writeln(e);
That is *SO* awesome!!
Thanks! Constant-space factorial is just a line away:
auto fact = series!("a[n] * (n + 1)")(1);
foreach (e; take(10, fact)) writeln(e);
writes:
1
1
2
6
24
120
720
5040
40320
362880
And this lousy series approximating pi:
auto piapprox = series!("a[n] + (n & 1 ? 4. : -4.) / (2 * n + 3)")(4.);
foreach (e; take(200, piapprox)) writeln(e);
Very slowly convergent. :o)
Nice! :-)
I showed the Fibonacci example to a friend of mine and he said "that
string stuff scares me a little". The same happens to me.
What kind of error do you get if you mistype something in that string
expression?
Can you pass a delegate instead of a string? Something like:
auto fib = series!((Range a, int n) { return a[n-1] + a[n]; })(1, 1);
That seems much safe and will probably give a reasonable error if you
mistype something. I know, it's longer than the previous one. But it
would be nice if D had the following rule (or something similar to it):
"if a delegate doesn't return, the last statement is converted to a
return" (and you can ommit the semicolon). So now you can write:
auto fib = series!((Range a, int n) { a[n-1] + a[n] })(1, 1);
And if you could just ommit the types in the delegate...
auto fib = series!((a, n) { a[n-1] + a[n] })(1, 1);
Still a little longer than the original, but you get all the benefits of
not using a string.
Ah... But I can see the problem with delegates. I guess with strings you
just mix them in a bigger expression and it's like inlining the call.
With delegates you can't do that. So there's also a performance tradeoff...