Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Import patterns

Two preludes cover everything most users need:

  • hylic::prelude::* — core: domain markers (Shared / Local / Owned), Shared-default Fold and Treeish constructors, 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::prelude and want Local constructors 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 explicitlyTraced, 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.

Module map
%3preludehylic::preludefold, treeish, FUSED, exec, funnel,SeedNode, lift atoms, explaineropshylic::opsFoldOps, TreeOpsprelude->opsnot re-exported (generic code only)exechylic::execExecutor, Exec, fused, funnelprelude->execre-exports public surfacedomhylic::domain::{shared,local,owned}Fold, edgy, FUSED, execprelude->domShared by defaultpphylic_pipeline::prelude=  hylic::prelude + pipeline types & sugarspp->preludere-exports