zilch/docs/modules/ROOT/pages/core/zexp.adoc
Puck Meerburg f0ce185d5c docs: Document core concepts
Change-Id: I6a6a6964d6bded229cd640463eaac70fd52df233
2025-11-14 13:01:04 +00:00

78 lines
2.7 KiB
Text

= ``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 val: foo>
(zexp-unwrap example)
;; #<zexp-evaluation val: foo; drvs: (); srcs: ()>
----
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
`<store-path>`, 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"
;; . #<store path /nix/store/mjs27ix6ig2bkbi3s3sm470vrv4lf7ic-hello
;; (/nix/store/76w21n1f03fs5kw8fnffphx7qrqffw6r-hello.drv!out)>))
(zexp-unwrap (cdar drv))
;; #<zexp-evaluation
;; val: "/nix/store/mjs27ix6ig2bkbi3s3sm470vrv4lf7ic-hello";
;; drvs: ((#<derivation …> "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)
;; #<zexp-evaluation
;; val: "The path for the derivation's output is /nix/store/mjs27ix6ig2bkbi3s3sm470vrv4lf7ic-hello";
;; drvs: ((#<derivation …> "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.