Looks weird, sorry.
Bash pipes make intuitive sense, you’re taking the output of one process and pushing it into another. Here, the use of pipes makes little sense. Why is “from alpine” being passed into “with-exec”? What is moving between those processes?
I see it as just the builder pattern that's pretty common in languages like Java. `container` is constructing the builder itself and eventually `terminal` (or other commands) use the state that has been incrementally built up in the builder to actually do something with the container.
Its the same idea. You are taking the instructions in with-exec and pushing it to the previous type.
In this case, `from alpine` is a function attached to the container type that has many additional functions. You chain them together to do stuff. You can do it through code as if it was any other object, but this shell allows you to do things without code as well.
Perhaps the example is too simple to feel useful, but being able to pipe primitives like files, directories, containers, secrets, and even any custom object makes it possible to rapidly experiment with and compose pipelines.
You're correct. As other comments pointed out, this is an OOP builder pattern:
`container().from('alpine').withExec(args: ["apk", "add"]).terminal()`
If it was unix pipes, they'd be context independent tools being composed together.
Dagger can be a useful but I feel a bit deceived, and it makes me worry about the rest of the quality of this product.
It’s similar to a builder pattern but not just a builder pattern because depending on the type you can indefinitely pipe context independent types.
So it’s a bit of a hybrid between bash and powershell.