In C++ with template metaprogramming you can calculate the fibonacci sequence in compile-time easily in this way.
template<int N>
constexpr int fibonacci() {return fibonacci<N-1>() + fibonacci<N-2>(); }
template<>
constexpr int fibonacci<1>() { return 1; }
template<>
constexpr int fibonacci<0>() { return 0; }
But in rust you cant just pass a constant through a generic as far as I know, also I know that sometimes rust optimizes some funcions to just constants in assmebly code. Example: https://rosettacode.org/wiki/Compile-time_calculation#Rust
But the conventional recursive approach of the problem is not optimized to a constant.
fn fibo(n: i32) -> i32 {
match n {
0 => 0,
1 => 1,
n => fibo(n - 1) + fibo(n - 2),
}
}
// Call it with
fibo(45); // It takes around 5 secs, calculated at runtime
Ok, to this point I can undestand that just the compiler does not know how to optimize this, but I found a way to make this calculated at compile time using Iterators!
struct Fibo(u32, u32);
impl Iterator for Fibo {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
*self = Fibo(self.1, self.1 + self.0);
Some(self.0)
}
}
fn fibo() -> Fibo {
Fibo(0, 1)
}
// Call it with
fibo().take(45).collect::<Vec<_>>()[44]; // This gets the 45th element calculated at compile-time, instantly
At this point I just want to know why this happens.