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.