///|
/// Package-private fixed-dependency `Derived` fast path.
///
/// This is deliberately not a public API. Static derived cells reuse the
/// existing pull backend (`MemoData` / `PullMemo`) and target facade handle, but
/// install their fixed dependency list once and recompute without opening a
/// dynamic tracking frame or diffing dependencies.
///|
priv struct StaticDerivedSource[T] {
rt : Runtime
id : CellId
read_declared : (CellId) -> T raise Failure
}
///|
fn Runtime::enter_static_recompute(self : Runtime) -> Unit {
let previous_runtime_id = if self.core.tracking.stack.is_empty() &&
self.static_recompute_depth == 0 {
None
} else {
@kernel.get_current_computing_runtime_id()
}
self.static_recompute_depth = self.static_recompute_depth + 1
self.static_recompute_tracking_floors.push(self.core.tracking.stack.length())
self.static_recompute_previous_runtime_ids.push(previous_runtime_id)
@kernel.set_current_computing_runtime_id(Some(self.core.runtime_id))
}
///|
fn Runtime::leave_static_recompute(self : Runtime) -> Unit {
guard self.static_recompute_depth > 0 &&
!self.static_recompute_tracking_floors.is_empty() &&
!self.static_recompute_previous_runtime_ids.is_empty() else {
abort("static recompute state underflow")
}
ignore(self.static_recompute_tracking_floors.pop())
let previous_runtime_id = self.static_recompute_previous_runtime_ids
.pop()
.unwrap()
@kernel.set_current_computing_runtime_id(previous_runtime_id)
self.static_recompute_depth = self.static_recompute_depth - 1
}
///|
fn Runtime::normalize_static_derived_deps(
self : Runtime,
deps : Array[CellId],
) -> Array[CellId] {
let seen : @hashset.HashSet[CellId] = @hashset.HashSet([])
let normalized : Array[CellId] = []
for dep in deps {
self.validate_cell(dep, "static derived dependency")
if !seen.contains(dep) {
seen.add(dep)
normalized.push(dep)
}
}
normalized
}
///|
fn[T] Runtime::install_static_derived(
self : Runtime,
deps : Array[CellId],
compute : (CellId) -> T raise Failure,
backdate_eq : (T, T) -> Bool,
label? : String,
) -> Derived[T] {
Derived::_create_static(self, deps, compute, label?, backdate_eq)
}
///|
fn[T] static_derived(
rt : Runtime,
deps : Array[CellId],
compute : () -> T raise Failure,
backdate_eq : (T, T) -> Bool,
label? : String,
) -> Derived[T] {
rt.install_static_derived(deps, _dependent => compute(), backdate_eq, label?)
}
///|
fn[T] static_source_input(source : Input[T]) -> StaticDerivedSource[T] {
{ rt: source.rt, id: source.id(), read_declared: _dependent => source.peek() }
}
///|
fn[T] static_source_input_field(
source : InputField[T],
) -> StaticDerivedSource[T] {
{
rt: source.input.rt,
id: source.input.id(),
read_declared: _dependent => source.peek(),
}
}
///|
fn[T] static_source_derived(source : Derived[T]) -> StaticDerivedSource[T] {
{
rt: source.rt,
id: source.id(),
read_declared: dependent => {
source.read_declared_fixed_dep_or_abort(dependent)
},
}
}
///|
fn[A, T : Eq] static_derived_map_source1(
source : StaticDerivedSource[A],
f : (A) -> T raise Failure,
label? : String,
) -> Derived[T] {
source.rt.install_static_derived(
[source.id],
dependent => f((source.read_declared)(dependent)),
(a, b) => a == b,
label?,
)
}
///|
fn[A, B, T : Eq] static_derived_map_sources2(
left : StaticDerivedSource[A],
right : StaticDerivedSource[B],
f : (A, B) -> T raise Failure,
label? : String,
) -> Derived[T] {
left.rt.install_static_derived(
[left.id, right.id],
dependent => {
f((left.read_declared)(dependent), (right.read_declared)(dependent))
},
(a, b) => a == b,
label?,
)
}
///|
fn[A, B, C, T : Eq] static_derived_map_sources3(
first : StaticDerivedSource[A],
second : StaticDerivedSource[B],
third : StaticDerivedSource[C],
f : (A, B, C) -> T raise Failure,
label? : String,
) -> Derived[T] {
first.rt.install_static_derived(
[first.id, second.id, third.id],
dependent => {
f(
(first.read_declared)(dependent),
(second.read_declared)(dependent),
(third.read_declared)(dependent),
)
},
(a, b) => a == b,
label?,
)
}
///|
fn[A, T : Eq] static_derived_map1(
source : Input[A],
f : (A) -> T raise Failure,
label? : String,
) -> Derived[T] {
static_derived_map_source1(static_source_input(source), f, label?)
}
///|
fn[A, T : Eq] static_derived_map_input_field1(
source : InputField[A],
f : (A) -> T raise Failure,
label? : String,
) -> Derived[T] {
static_derived_map_source1(static_source_input_field(source), f, label?)
}
///|
fn[A, T : Eq] static_derived_map_derived1(
source : Derived[A],
f : (A) -> T raise Failure,
label? : String,
) -> Derived[T] {
static_derived_map_source1(static_source_derived(source), f, label?)
}
///|
fn[A, B, T : Eq] static_derived_map2(
left : Input[A],
right : Input[B],
f : (A, B) -> T raise Failure,
label? : String,
) -> Derived[T] {
static_derived_map_sources2(
static_source_input(left),
static_source_input(right),
f,
label?,
)
}
///|
fn[A, B, C, T : Eq] static_derived_map3(
first : Input[A],
second : Input[B],
third : Input[C],
f : (A, B, C) -> T raise Failure,
label? : String,
) -> Derived[T] {
static_derived_map_sources3(
static_source_input(first),
static_source_input(second),
static_source_input(third),
f,
label?,
)
}