Import patterns
Two preludes cover everything most users need:
hylic::prelude::*— core: domain markers (Shared/Local/Owned), Shared-defaultFoldandTreeishconstructors, executor helpers (FUSED,exec), every lift atom (Lift,IdentityLift,ComposedLift,ShapeLift,SeedLift,LiftBare,SeedNode), and explainer/format helpers.hylic_pipeline::prelude::*— re-exports the core prelude plus pipeline typestates (SeedPipeline,TreeishPipeline,Stage2Pipeline,OwnedPipeline), source traits (TreeishSource,PipelineExec,PipelineExecOnce,PipelineSourceOnce), and the sugar trait families (SeedSugars*,TreeishSugars*,Stage2Sugars*).
A complete program — fold + graph + executor — needs exactly one prelude line:
#![allow(unused)]
fn main() {
use hylic::prelude::*;
let fold = fold(|n: &i32| *n as u64,
|h: &mut u64, c: &u64| *h += c,
|h: &u64| *h);
let graph = treeish(|n: &i32| if *n > 1 { vec![n - 1, n - 2] } else { vec![] });
let total = FUSED.run(&fold, &graph, &5);
}
FUSED is the sequential executor, available as a const on the
Shared domain. fold and treeish are the Shared-default
constructors — for Local or Owned, take the per-domain path
(below).
Switching domains
For Local or Owned construction, address the domain module
directly. The closures don’t change; only the constructor and the
executor binding do:
#![allow(unused)]
fn main() {
#[test]
fn domain_switching() {
use hylic::domain::{shared as sdom, local as ldom, owned as odom};
use hylic::graph::treeish_visit;
#[derive(Clone)]
struct N { val: u64, children: Vec<N> }
// Same closures used to build a fold in each domain.
let init = |n: &N| n.val;
let acc = |h: &mut u64, c: &u64| *h += c;
let fin = |h: &u64| *h;
fn children(n: &N, cb: &mut dyn FnMut(&N)) {
for c in &n.children { cb(c); }
}
let root = N { val: 1, children: vec![N { val: 2, children: vec![] }] };
// Shared (Arc):
let r1: u64 = sdom::FUSED.run(
&sdom::fold(init, acc, fin),
&treeish_visit(children),
&root,
);
// Local (Rc):
let r2: u64 = ldom::FUSED.run(
&ldom::fold(init, acc, fin),
&treeish_visit(children),
&root,
);
// Owned (Box):
let r3: u64 = odom::FUSED.run(
&odom::fold(init, acc, fin),
&treeish_visit(children),
&root,
);
assert_eq!(r1, r2);
assert_eq!(r2, r3);
}
}
Parallel execution
Funnel comes in through the prelude as the funnel module:
#![allow(unused)]
fn main() {
use hylic::prelude::*;
let total = exec(funnel::Spec::default(8)).run(&fold, &graph, &root);
}
Spec presets (default, for_wide_light, for_deep_narrow, …)
are documented in Funnel policies. For
amortised pool reuse across many folds, use
.session(|s| s.run(...)).
Pipeline programs
Pipelines layer on the same imports — switch to the pipeline prelude:
#![allow(unused)]
fn main() {
use hylic_pipeline::prelude::*;
}
That single line brings the core prelude with it; users do not
import hylic::prelude separately. From there, every Stage-1
constructor (SeedPipeline::new, TreeishPipeline::new,
OwnedPipeline::new) and every sugar (.lift(), .then_lift(…),
.zipmap(…), .wrap_init(…), .explain(), .run(…)) is in
scope.
A full pipeline example is at the end of Pipelines — overview.
When you need bare module paths
The preludes cover normal usage. The bare module paths are useful for
-
Generic code over executors or operations
#![allow(unused)] fn main() { use hylic::ops::{FoldOps, TreeOps}; use hylic::exec::Executor; } -
Per-domain primitives (e.g. when you keep
hylic::preludeand wantLocalconstructors visible at the same names): import the domain module under an alias —#![allow(unused)] fn main() { use hylic::domain::local as ldom; let lf = ldom::fold(|n: &i32| *n as u64, |h: &mut u64, c: &u64| *h += c, |h: &u64| *h); ldom::FUSED.run(&lf, &graph, &root); } -
Helpers under
hylic::prelude::*that come in via the wildcard but are sometimes worth naming explicitly —Traced,memoize_treeish,VecFold,vec_fold, the explainer trace formatters,TreeFormatCfg. Reach for the qualified path when the call site benefits from the extra signal at a glance.