Hacker News new | ask | show | jobs
by evancordell 1543 days ago
I played with a similar idea a while ago: https://github.com/ecordell/cuezel/ (cuezel as in: "Bazel but with CUE"), but I was never sure that what I was doing was in the spirit of CUE.

CUE pushes nondeterminism into "_tool.cue"[0] files that are allowed to do things like IO and run external processes. Tool files scratch a similar itch to Makefiles, but they lack an integrated plugin system like Bazel (hence why I played with the idea of CUE + Bazel).

With Dagger you seem to be restricted to the set of things that the dagger tool can interpret, just like with my Cuezel tool you are limited to what I happened to implement.

In CUE `_tool` files you are also limited to the set of things that the tool builtins provide, but the difference is that you know that the rest of the CUE program is deterministic/pure (everything not in a _tool file).

There's clearly value in tooling that reads CUE definitions, and dagger is the first commercial interest in CUE that I've seen, which is exciting.

But I'm most interested in some CUE-interpreter meta-tool that would allow you to import cue definitions + their interpreters and version them together, but for use in `_tool` files to keep the delineation clear. Maybe this is where dagger is heading? (if so it wasn't clear from the docs)

[0]: https://pkg.go.dev/cuelang.org/go@v0.4.2/pkg/tool

1 comments

I know exactly what you mean. Earlier versions of Dagger actually took this "embedding" approach: any CUE configuration is a valid Dagger configuration, with an extra layer of annotation that describes how to make that configuration runnable. What we learned is that this model is thoroughly confusing to almost everyone except hardcore CUE enthusiasts.

Now we use CUE in a more straightforward way: as a superior replacement for YAML. There's a (simple) schema that all Dagger plans must follow; beyond that, you can import any CUE package and apply any definition into your plan. But you don't need to go upstream and annotate these packages with additional Dagger metadata.

I'm not sure if my explanation is clear - even I get confused by this embedding business sometimes.

In the examples it looked as though there is still a CUE unification loop happening during dagger processing:

  deploy: netlify.#Deploy & {
    contents: build.contents.output
  }
It looks like dagger is using cue as a bit more than a YAML replacement; it hydrates cue values as it runs - which is cool! - but that's the part that seemed at odds with CUE's philosophy of pushing nondeterminism into clearly marked files.
Yes, we use CUE as more than just a YAML replacement. In particular we use CUE references to construct the DAG and "compile" it to buildkit.

And, yes, Dagger will gradually fill the missing values in the CUE tree during runtime. Essentially resolving the DAG on the fly. It is pretty cool :)

We have discussed this topic at length with the CUE developers. Our conclusion is that CUE's deterministic core is what matters, and the `_tool.cue` pattern is more peripheral: more of a reference for how other tools might use cue for non-deterministic operations. It's not realistic for CUE to be both a ubiquitous deterministic language, and a successful non-deterministic tool. Its priority is clearly the former, and we're focusing on the latter.