# [−][src]Crate recur_fn

A library that provides a more flexible way to construct and extend the recursive function.

The `RecurFn` trait is an abstraction of a recursive function. By accepting a function parameter `recur` as the recursion rather than recurring directly, it makes constructing an anonymous recursive function possible.

```use recur_fn::{recur_fn, RecurFn};

let fib = recur_fn(|fib, n: i32| {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
});

assert_eq!(55, fib.call(10));```

Beside, it makes extending the body of a recursive function possible.

```use recur_fn::{recur_fn, RecurFn};
use std::cell::RefCell;

let fib = recur_fn(|fib, n: i32| {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
});

let log = RefCell::new(Vec::new());

let fib_with_logging = recur_fn(|recur, n: i32| {
log.borrow_mut().push(n);
fib.body(recur, n)
});

fib_with_logging.call(3);
assert_eq!(*log.borrow(), vec![3, 2, 1, 0, 1]);```

As `recur_fn` is a convenient way to construct a `RecurFn`, calling it is slower than direct recursion. To make it zero-cost, consider defining a struct, implementing `RecurFn` trait for it and mark the `body` method by `#[inline]`.

```use recur_fn::RecurFn;

let fib = {
struct Fib {}
impl RecurFn<i32, i32> for Fib {
#[inline]
fn body(&self, fib: impl Fn(i32) -> i32, n: i32) -> i32 {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
}
}
Fib {}
};

assert_eq!(55, fib.call(10));```

or if the function doesn't capture anything, you can use `recur_fn` macro.

```use recur_fn::{recur_fn, RecurFn};

let fact = recur_fn!(fact(n: i32) -> i32 {
if n == 0 { 1 } else { n * fact(n - 1) }
});
assert_eq!(6, fact.call(3));
assert_eq!(0,
fact.body(|_| 0, 3));```

`DynRecurFn` is a dynamic version of `RecurFn` that allows you to have a trait object.

```use recur_fn::{recur_fn, RecurFn, DynRecurFn};
use core::ops::Deref;

let dyn_fact: &dyn DynRecurFn<_, _> =
&recur_fn(|fact, n: i32| if n == 0 { 1 } else { n * fact(n - 1) });```

## Macros

 recur_fn Expands a function definition to defining a struct, implementing `RecurFn` for the struct and constructing it. It can be useful if you want a zero-cost `RecurFn` implementation.

## Structs

 Closure A `RecurFn` that uses a closure as the body. Direct A `RecurFn` that doesn't call `recur` parameter in its body. FromPointer A `RecurFn` that delegates to a pointer to a `RecurFn`.

## Traits

 DynRecurFn The dynamic version of `RecurFn` that supports trait object. RecurFn The recursive function trait.

## Functions

 direct Constructs a non-recursive `RecurFn` calling `f` directly. from_pointer Returns a `RecurFn` implementation from a pointer to `RecurFn`, i.e. a implementation of `Deref` whose `Target` implements `RecurFn`. recur_fn Constructs a `RecurFn` with the body speicified.