fn fib(n: int, f: fn (num: i64) -> bool) -> (i64, int) { if n < 0 { // Let these variables be mutated, otherwise too slow let mut n1:i64 = 0, n2:i64 = -1, i:int = 0, tmp:i64; while i > n { f(n1); tmp = n1-n2; if (tmp > 0 && n2 > 0) { //Detect overflow io::println("\nReached the limit of i64, halting"); return (n1, i); } n1 = n2; n2 = tmp; i -= 1; } (n1+n2, n) } else if n > 0 { // And these variables let mut n1:i64 = 0, n2:i64 = 1, i:int = 0, tmp:i64; while i < n { f(n1); tmp = n1+n2; if (tmp < 0) { //Detect overflow io::println("\nReached the limit of i64, halting"); return (n1, i); } n1 = n2; n2 = tmp; i += 1; } (n2-n1, n) } else { f(0); (0,1) } } fn main() { let args = os::args(); let n = if args.len() == 1 { 10 } else if args.len() > 1 { // Convert from a string match (int::from_str(args[1])) { Some(num) => num, None => 10 //Fall back to default } } else { /* Required to use the if as an expression. * We know that args.len() is always >= 1, the compiler * does not. fail lets it know that we can't get past here. */ fail ~"No arguments given, somehow..."; }; /* Use the loop protocol to be able to do things * with the sequence given, in this case, print them out. * The loop itself returns a tuple with where it got to and * what the number is. */ let (result, n) = for fib(n) |num| { //print out the sequence io::print(fmt!("%? ", num)); }; io::println(fmt!("\nThe %dth fibonacci number is: %?", n, result)); }