= ``zexp``s, store paths, and context :page-pagination: In Nix, strings carry around a "context", corresponding to a list of dependencies that string has. For example, the `outPath` of a derivation in Nix has a context that contains its derivation, plus the output name. When strings are concatenated, their contexts are merged together. In Zilch, a similar concept exists; encapsulated in so-called "zexpressions". A `zexpr` is a lazily evaluated thunk that, when evaluated, has access to other ``zexpr``s and closely related objects. When a `zexpr` is unwrapped, it returns the resulting value, plus a list of derivations and outputs that are depended on. [source,scheme] ---- (define example (zexp foo)) ;; # (zexp-unwrap example) ;; # ---- The primary way a zexp that contains context is made, is by using xref:generated:zilch.magic.adoc#store-path-for-drv[`store-path-for-drv`] and xref:generated:zilch.magic.adoc#store-path-for-ca-drv[`store-path-for-ca-drv`]. This returns a ``, which can be unwrapped like a `zexp`. [source,scheme] ---- (define drv (store-path-for-drv "hello" "x86_64-linux" '("/bin/sh" "-c" "echo hi > $out") '() '("out")) ;; (("out" ;; . #)) (zexp-unwrap (cdar drv)) ;; # "out")); ;; srcs: ()> ---- A `zexp` behaves similarly to the `quasiquote` macro, in that it is possible to use `unquote` (or its reader syntax) to unquote values. Unquoting a `zexp`, however, requires a special mechanism, and is executed before `unquote`. This allows for full expressiveness when generating, for example, arguments or environments for derivations. [source,scheme] ---- (define complex (zexp (unquote (string-append "The path for the derivation's output is " (zexp-unquote (cdar #3))))) (zexp-unwrap complex) ;; # "out")); ;; srcs: ()> ---- A store path, after being created by `store-path-for-(ca-)drv`, is not guaranteed to exist in the store. To ensure it exists, xref:generated:zilch.magic.adoc#store-path-materialize[`store-path-materialize`] is used; this is transparently done when a `store-path` is unwrapped inside a `zexp`. == Reader syntax For convenience, `+#~foo+` is used as reader syntax for `(zexp foo)`, while `+#$foo+` and `+#$@foo+` are syntax for `(zexp-unwrap foo)` and `(zexp-unquote-splicing foo)` respectively.