use std::cell::Cell;
use std::rc::Rc;
use tincan::Scope;
fn main() {
println!("=== Derived State Example ===\n");
let cx = Scope::new();
let first_name = cx.signal(String::from("Alice"));
let last_name = cx.signal(String::from("Smith"));
let age = cx.signal(30);
let full_name = cx.memo({
let first = first_name.clone();
let last = last_name.clone();
move || format!("{} {}", first.get(), last.get())
});
let greeting = cx.memo({
let name = full_name.clone();
let age = age.clone();
move || format!("Hello, {}! You are {} years old.", name.get(), age.get())
});
let greeting_clone = greeting.clone();
let _display = cx.effect(move || {
println!("👋 {}", greeting_clone.get());
});
println!("Updating first name...");
first_name.set(String::from("Bob"));
println!("\nUpdating age...");
age.set(35);
println!("\nUpdating last name...");
last_name.set(String::from("Johnson"));
println!("\n=== Memoization Efficiency ===\n");
let cx2 = Scope::new();
let input = cx2.signal(5);
let computation_count = Rc::new(Cell::new(0));
let expensive_computation = cx2.memo({
let input = input.clone();
let computation_count = Rc::clone(&computation_count);
move || {
computation_count.set(computation_count.get() + 1);
println!("🔄 Computing... (count: {})", computation_count.get());
input.get() * input.get()
}
});
println!("First access:");
println!("Result: {}", expensive_computation.get());
println!("\nSecond access (should use cache):");
println!("Result: {}", expensive_computation.get());
println!("\nThird access (should still use cache):");
println!("Result: {}", expensive_computation.get());
println!("\nChanging input:");
input.set(10);
println!("Accessing after change (should recompute):");
println!("Result: {}", expensive_computation.get());
println!("\nAccessing again (should use cache):");
println!("Result: {}", expensive_computation.get());
println!("\nTotal computations: {}", computation_count.get());
println!("\n=== Diamond Dependency ===\n");
let cx3 = Scope::new();
let root = cx3.signal(10);
let double = cx3.memo({
let root = root.clone();
move || {
let val = root.get() * 2;
println!(" Computing double: {}", val);
val
}
});
let triple = cx3.memo({
let root = root.clone();
move || {
let val = root.get() * 3;
println!(" Computing triple: {}", val);
val
}
});
let sum = cx3.memo({
let double = double.clone();
let triple = triple.clone();
move || {
let val = double.get() + triple.get();
println!(" Computing sum: {}", val);
val
}
});
println!("Initial computation:");
println!("Sum: {}\n", sum.get());
println!("Accessing again (should use all caches):");
println!("Sum: {}\n", sum.get());
println!("Changing root value:");
root.set(20);
println!("Sum: {}", sum.get());
}