#Type extensions
1 messages ยท Page 1 of 1 (latest)
๐งต FYI @gray carbon @dull canopy @mellow halo @copper wraith
Type extensions
I'll start by listing the various concerns / requirements:
- Adding fields to
ContainerandDirectoryfeels cool and useful. (co-signed by @copper wraith and @smoky anvil from our user experience so far)
- At the same time, adding fields to core types creates the risk of naming conflicts, and there is consensus that Dagger should namespace automatically, so that conflicts are not possible. There are several ways to do this, and we need to decide on one.
- Beyond naming conflicts, there's a more gut-level concern of extending core types feeling "weird" or "scary". This was experienced by @mellow halo and later by @dull canopy . Whatever we design, we should run it by the "gut feeling check".
- Extending the query type: at the moment a module can only add one field to Query. The field name is always <MODULENAME> and it cannot take arguments. As a module developer I would like more control over that.
why do you need arguments to modules? You can pass arguments to functions of the modules, no?
yes, but it's just part of the expressiveness of GraphQL that is not available to me
for example in the Dagger API:
query {
git(url: "github.com/dagger/dagger") {
branch(name: "main") {
tree {
...
}
}
}
}
I can't do that in my module
For example in my dagger module (kind of meta, a dagger module to download and build dagger), I felt the need for it
I have to do:
query {
dagger {
cli(version: "0.8.5") {
...
}
sourceRelease(version: "0.8.5") {
...
}
}
}
But I would prefer to do:
query {
dagger(version: "0.8.5) {
cli {
...
}
sourceRelease {
...
}
}
}
i see
My concern was that it isn't always clear whether a function call returns a module, or a container. So like in chain.Golang().GoBuild() is Golang() the module or is it some magical extension that returns a golang container ?
Note that this design does not exist, so we're talking about imaginary code ๐
With that in mind, I think chain.Golang(), would return a struct type, generated by the engine, which would be a wrapper of the original container. The details are a bit blurry because we're getting into more advanced relationships between types, that we haven't needed to use so far
I think I can make something like this work right now if we need a tangible example
back after a long lunch meeting..
@mellow halo ๐
Beyond naming conflicts, there's a more gut-level concern of extending core types feeling "weird" or "scary". This was experienced by @mellow halo and later by @dull canopy .
Yeah, that was my reaction as well. Besides, it's not as easily done in other languages without getting magical, or merging types by name.
Do you have ideas on how to adapt the design without losing the feature altogether?
We had a discussion with @supple hamlet last night / this morning for you, that led to a configurable "type casting" that I think could be the solution
- Instead of this:
directory.goBuild - Maybe this:
directory.asGoProject.build
I'm not sure about the diff.
In the first case (current situation), a module can monkeypatch core types at will
In the second case (imaginary design), monkeypatching is not possible. Instead, modules can register type "specializations". For example, the module go can register its custom type Project as a possible specialization of Container. The result is <coretype>.as<moduleName><specializedType>. In this case: Container.asGoProject.
The Go SDK could use Go type embedding for this. If a module type embeds a core type, the SDK can register that as a specialized type