https://github.com/vito/dang
Experimental GraphQL scripting language
https://github.com/vito/dang
dagger graphql hindley-milner language
Last synced: about 1 month ago
JSON representation
Experimental GraphQL scripting language
- Host: GitHub
- URL: https://github.com/vito/dang
- Owner: vito
- License: apache-2.0
- Created: 2025-07-13T21:24:58.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2026-01-13T19:53:08.000Z (about 2 months ago)
- Last Synced: 2026-01-13T21:44:30.969Z (about 2 months ago)
- Topics: dagger, graphql, hindley-milner, language
- Language: Go
- Homepage:
- Size: 5.28 MB
- Stars: 6
- Watchers: 0
- Forks: 2
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# dang.
`dang` is a statically typed language for scripting GraphQL, where the types and functions are loaded directly from the schema.
## sample
Here's `.dagger/main.dang` at the time of this writing:
```graphql
type Dang {
pub source: Directory! @defaultPath(path: "/") @ignorePatterns(patterns: [
"Session.vim"
"/dang"
"/zed-dang/grammars/",
"/.env"
])
pub build: File! {
go(source).binary("./cmd/dang")
}
pub test: Container! {
go(source).base.
withDirectory("/src", source).
withWorkdir("/src").
withExec(["go", "test", "-v", "./..."], experimentalPrivilegedNesting: true)
}
}
```
## why?
The initial goal was a native language for [Dagger]. Dagger is a polyglot
function engine with an underlying GraphQL API serving as the common layer where
functions written in different languages call one another.
Combining Dang with Dagger gives you a polyglot language with an ecosystem of
modules developed in any language that has a [Dagger SDK]. Dang is one such
Dagger SDK, so it's perfect for writing Dagger modules that simply glue together
APIs and don't need a heavy full-blown language runtime. As a result of not
needing a codegen phase, it has potential to be much, much faster than the other
SDKs.
Architecturally, Dang is decoupled from Dagger; it just speaks GraphQL, so you
can point it at any API endpoint you want.
[Dagger]: https://dagger.io
[Dagger SDK]: https://docs.dagger.io/api/sdk/
## design philosophy
* **familiarity** over theory
- I've had my fun with language design/impl, time to make one people might actually use. :)
* **ergonomics** over syntactic purity
- Embrace keywords and first-class syntax for common patterns. Don't obsess over homoiconicity and macros.
* **expressiveness** over performance
- This is a glue language; it's unlikely to be the bottleneck. Dev performance is more important than runtime performance.
* **safety** over ... uh ... danger
- I should be able to have some confidence in my "production-shipping glue code" without having to ship to production.
* **be a leaf in the wind**
- Dang shouldn't take too much brain juice; that's already been spent on the product that it's used to build/test/ship.
### cute bits
* **multi-field selection**
- `user.{name, posts.{title, createdAt}}}` fetches everything in one query
* **null tracking**
- `String` does not satisfy `String!`, but `String!` satisfies `String`
* **optional parentheses** for functions without required args
- `container() == container`
* **named arguments** with **positional shorthand**
- `container.from(address: "foo") == container.from("foo")`
* **directives**
- structural type-checked metadata (`@defaultPath(...)`) instead of comment pragmas
* **prototype-based objects**
- `type Foo(bar: String!) { ... }` declares a new `Foo` type and `Foo("xyz")` constructor
* **directory-level loading**
- Similar to Go; split your code up at your liesure.
## how the meat was made
This language needs to be maintainable in very limited time as a side project.
To that end:
* There's a single [Pigeon] grammar from which a [Tree-sitter] grammar is
generated, so I don't have to maintain both. Feel free to steal this for your
own esolang!
* The language has a built-in `assert { ... }` syntax so that I can test it at
a very high level (a Big Pile of Dang Scripts).
* Large swathes of the codebase have been implemented with AI. The language
design is still my fault, but I've let AI do a lot of the typing.
Personally, having already created [Bass] recently I didn't feel the
motivation to start all over again. It didn't seem like I'd learn much along
the way, so it wasn't worth spending whatever mileage my fingers have left.
This was a great opportunity to learn about AI and reach my project goals at
the same time, so I took that direction instead.
This project sat unfinished for 2 years, and in a day of AI crunching I was
finally able to bring it to life. If you have ethical concerns with this or
think that makes the project lame, I respect that. If you can, just pretend
this project stayed in that unfinished state. Maybe check out [Bass] instead,
which may be more interesting to language nerds anyway. :)
If it's any consolation, I will not be using AI for the parts that interface
with humans. This README is 100% farm-raised, and the documentation and logo
will be, too. (I might use AI for tedious website stuff, but not the
content.)
[Bass]: https://github.com/vito/bass
[Pigeon]: https://github.com/mna/pigeon
[Tree-sitter]: https://tree-sitter.github.io/tree-sitter/
## thanks
Special thanks to [@chewxy] for writing the [hm] package - having never
implemented a typed language before, I initially leaned on this heavily.
Eventually I had AI re-write a local version so I can better integrate it into
Dang's local dialect, but I learned a lot from the original package, and its
existence was the spark that led to Dang's creation.
[@chewxy]: https://github.com/chewxy
[hm]: https://github.com/chewxy/hm