The Starlark Programming Language
What Starlark Is and Where It’s Used
- Python-like, intentionally restricted language originally for Bazel/Blaze build rules.
- Now framed as a general-purpose embeddable language, with implementations in Java (original/Bazel-tied), Go (generic embedding), and Rust (used in Buck2, with extra features).
- Also used in tools like Buck2, Tilt, internal Go-based tools, a smart display platform (Tidbyt), a Go-based internal tools platform, and GitHub automation.
Design Goals: Hermetic, Deterministic, Turing-Incomplete
- No access to time, randomness, filesystem, network, or environment by default; host controls all side-effecting APIs.
- Deterministic evaluation: same inputs → identical outputs; avoids nondeterminism from random seeds, hash ordering, system APIs.
- Turing-incomplete (e.g., no recursion), which some see as a feature for config/build languages and a draw versus typical embeddable languages.
Strengths Reported
- Familiar Python-like syntax lowers onboarding cost versus Lua/Lisp-like options.
- Hermeticity and determinism aid reproducible, cacheable, parallel builds in very large monorepos.
- Simpler, smaller “safe” runtime than embedding full Python or JS/WASM and trying to sandbox them.
- Go implementation is easy to embed; performance and concurrency reported as good.
- Works well as a controlled scripting layer or “contract/config language” for apps and infrastructure.
Pain Points and Critiques
- Large Starlark codebases resemble messy large Python codebases: imperative, highly indirect, and hard to reason about.
- Language minimalism: no standard exceptions, no multi-value returns for errors, limited data structures; error handling requires patterns like Result wrappers or custom host mechanisms.
- Inconsistent behavior between implementations (Bazel vs Go vs Rust) noted.
- Some find it one of the most complicated languages to read in practice given abstraction layers in real build rules.
- Close resemblance to Python can mislead users expecting modern Python features (pattern matching, walrus operator, full stdlib).
- Skepticism about maintaining yet another DSL vs using established languages (Lua, Python, Kotlin/Gradle) or pure data configs.
Types and Tooling Debate
- Core Starlark lacks Python-style static typing; this is widely seen as a major weakness for large codebases.
- Rust implementation for Buck2 adds type annotations and an LSP; Go/Bazel side has some autocomplete via bazel-lsp, but overall tooling is weaker than typed languages.
- Long subthread debates what “typed/untyped/strong/weak” really mean; consensus in practice is that Starlark behaves like dynamically typed Python without mature static checking.
Alternatives and Broader Reflections
- Other Turing-incomplete or config-focused options mentioned: CUE and Dhall, with more formal type systems.
- Some argue build systems should embrace full, strongly typed languages (e.g., Kotlin/Gradle, Scala-based tools) rather than restricted DSLs; others prefer non–Turing-complete, declarative configs to keep builds understandable and safe from overengineering.