Lifetime parameters in relations
ekzhang opened this issue · 0 comments
ekzhang commented
Right now, Crepe recommends that you pass references to types like Strings in relations, rather than values. This is for efficiency reasons, as relations are required to implement the Copy
trait. For example, the following code is valid:
use crepe::crepe;
crepe! {
@input
struct Edge(&'static str, &'static str);
@output
struct Reachable(&'static str, &'static str);
// Transitive closure
Reachable(n, m) <- Edge(n, m);
Reachable(n, m) <- Edge(n, k), Reachable(k, m);
}
fn main() {
let mut runtime = Crepe::new();
runtime.extend(&[
Edge("hello", "world"),
Edge("world", "foo"),
Edge("world", "bar"),
]);
let (reachable,) = runtime.run();
println!("Reachable: {}", reachable.len());
for Reachable(x, y) in reachable {
println!("edge: {} -> {}", x, y);
}
}
However, with non-'static
lifetimes, Rust requires that the struct
declaration be generic over the lifetime parameter. Currently Crepe does not check for this, but it would be useful to write code with non-static lifetimes such as:
use crepe::crepe;
crepe! {
@input
struct Edge<'a>(&'a str, &'a str); // does not compile currently
@output
struct Reachable<'a>(&'a str, &'a str); // does not compile currently
// Transitive closure
Reachable(n, m) <- Edge(n, m);
Reachable(n, m) <- Edge(n, k), Reachable(k, m);
}
fn main() {
let dyn_string = String::from("dynamic");
let mut runtime = Crepe::new();
runtime.extend(&[
Edge("hello", "world"),
Edge("world", "foo"),
Edge("world", "bar"),
Edge("world", &dyn_string),
]);
let (reachable,) = runtime.run();
println!("Reachable: {}", reachable.len());
for Reachable(x, y) in reachable {
println!("edge: {} -> {}", x, y);
}
}