Convert Figma logo to code with AI

bazelbuild logostarlark

Starlark Language

2,426
160
2,426
87

Top Related Projects

1,187

Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]

5,227

HCL is the HashiCorp configuration language.

Maintainable configuration files

Common Expression Language -- specification and binary representation

8,555

A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.

Quick Overview

Starlark is a dialect of Python designed for use as a configuration language. It is the primary language used in Bazel build files and is also used in other tools like Buck and Pants. Starlark aims to be simple, small, and hermetic, making it suitable for configuration purposes.

Pros

  • Familiar syntax for Python developers
  • Deterministic evaluation, which is crucial for reproducible builds
  • Designed for configuration, with limitations that prevent unintended side effects
  • Extensible through custom built-in functions and types

Cons

  • Limited standard library compared to full Python
  • No support for certain Python features like classes or recursion
  • Learning curve for developers not familiar with Python or Bazel
  • Can be verbose for complex configurations

Code Examples

  1. Defining a simple rule:
def _impl(ctx):
    output = ctx.actions.declare_file(ctx.label.name + ".txt")
    ctx.actions.write(output=output, content="Hello, World!")
    return [DefaultInfo(files = depset([output]))]

hello_world = rule(
    implementation = _impl,
    attrs = {},
)
  1. Using a macro to simplify rule usage:
def hello_library(name):
    hello_world(
        name = name + "_rule",
    )
    native.filegroup(
        name = name,
        srcs = [name + "_rule"],
    )
  1. Loading and using external dependencies:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "com_google_protobuf",
    urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.19.1.zip"],
    strip_prefix = "protobuf-3.19.1",
)

Getting Started

To use Starlark in a Bazel project:

  1. Install Bazel: https://docs.bazel.build/versions/main/install.html
  2. Create a WORKSPACE file in your project root:
workspace(name = "my_project")
  1. Create a BUILD file in your source directory:
load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
    name = "hello_world",
    srcs = ["hello_world.cc"],
)
  1. Write your Starlark code in .bzl files and load them in your BUILD files as needed.

Competitor Comparisons

1,187

Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]

Pros of Skylark

  • More actively maintained with recent updates and contributions
  • Includes additional tools and utilities for working with Starlark
  • Better documentation and examples for users

Cons of Skylark

  • Less integrated with the Bazel ecosystem
  • Smaller community and fewer contributors
  • May have compatibility issues with some Bazel-specific features

Code Comparison

Skylark:

def my_rule_impl(ctx):
    output = ctx.actions.declare_file(ctx.label.name + ".out")
    ctx.actions.run_shell(
        outputs=[output],
        command="echo 'Hello, Skylark!' > {}".format(output.path),
    )
    return [DefaultInfo(files=depset([output]))]

Starlark:

def my_rule_impl(ctx):
    output = ctx.actions.declare_file(ctx.label.name + ".out")
    ctx.actions.run_shell(
        outputs=[output],
        command="echo 'Hello, Starlark!' > {}".format(output.path),
    )
    return [DefaultInfo(files=depset([output]))]

The code comparison shows that both implementations are nearly identical, with the main difference being the project name in the output message.

Pros of go-jsonnet

  • Designed specifically for configuration management and data templating
  • Supports advanced features like import statements and library functions
  • Offers a more expressive and flexible syntax for complex data structures

Cons of go-jsonnet

  • Less integrated with build systems compared to Starlark
  • May have a steeper learning curve for users unfamiliar with JSON-based languages
  • Limited use cases outside of configuration management

Code Comparison

Starlark:

def greet(name):
    return "Hello, " + name + "!"

result = greet("World")
print(result)

go-jsonnet:

local greet(name) = "Hello, " + name + "!";

{
  result: greet("World")
}

Summary

While Starlark is primarily designed for build system configuration and scripting, go-jsonnet focuses on data templating and configuration management. Starlark offers tighter integration with build tools like Bazel, while go-jsonnet provides more flexibility for complex data structures and configuration scenarios. The choice between the two depends on the specific use case and the ecosystem in which they'll be used.

5,227

HCL is the HashiCorp configuration language.

Pros of HCL

  • More flexible syntax, allowing for both configuration and data representation
  • Native support for JSON-like structures and heredocs
  • Designed for human-readability and ease of use in configuration files

Cons of HCL

  • Less focused on programming language features compared to Starlark
  • May be less suitable for complex scripting or programming tasks
  • Limited built-in functions and standard library compared to Starlark

Code Comparison

HCL:

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "ExampleInstance"
  }
}

Starlark:

def create_instance(ami, instance_type, name):
    return {
        "ami": ami,
        "instance_type": instance_type,
        "tags": {"Name": name},
    }

example = create_instance("ami-0c55b159cbfafe1f0", "t2.micro", "ExampleInstance")

The HCL example shows its declarative nature and built-in support for resource definitions, while the Starlark example demonstrates its more programmatic approach with functions and variable assignments.

Maintainable configuration files

Pros of dhall-lang

  • Strong type system with support for dependent types, offering more advanced type-checking capabilities
  • Built-in support for importing and referencing external files, enhancing modularity
  • Language-agnostic design, allowing for broader application across different programming ecosystems

Cons of dhall-lang

  • Steeper learning curve due to its more complex type system and functional programming concepts
  • Smaller community and ecosystem compared to Starlark, potentially leading to fewer resources and tools

Code Comparison

Dhall example:

let Config = { name : Text, age : Natural }
let person = { name = "Alice", age = 30 } : Config
in  person

Starlark example:

def create_person(name, age):
    return {"name": name, "age": age}

person = create_person("Alice", 30)

Both examples create a simple configuration structure, but Dhall's static typing and explicit type declarations contrast with Starlark's more Python-like dynamic approach.

Common Expression Language -- specification and binary representation

Pros of cel-spec

  • Designed specifically for expression evaluation in configuration and policy scenarios
  • Supports gradual typing, allowing for more flexible and dynamic expressions
  • Includes built-in support for protocol buffers and common data types

Cons of cel-spec

  • Less mature and less widely adopted compared to Starlark
  • Limited to expression evaluation, not suitable for full scripting capabilities
  • Smaller ecosystem and fewer available tools and integrations

Code Comparison

cel-spec:

name.startsWith("foo") && auth.user == "admin" && request.time < now - duration("24h")

Starlark:

def check_condition(name, auth, request, now):
    return (name.startswith("foo") and
            auth.user == "admin" and
            request.time < now - timedelta(hours=24))

Summary

cel-spec is tailored for expression evaluation in configuration and policy contexts, offering gradual typing and built-in support for common data types. However, it has a smaller ecosystem and is less mature than Starlark. Starlark, being a more complete scripting language, offers greater flexibility but may be overkill for simple expression evaluation tasks. The choice between the two depends on the specific use case and requirements of the project.

8,555

A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.

Pros of Buck

  • More comprehensive build system with advanced features like caching and distributed builds
  • Supports multiple programming languages and platforms out-of-the-box
  • Extensive documentation and active community support

Cons of Buck

  • Steeper learning curve due to its complexity
  • Heavier resource usage, especially for smaller projects
  • Less flexibility in customizing build rules compared to Starlark

Code Comparison

Buck:

android_binary(
    name = "app",
    manifest = "AndroidManifest.xml",
    keystore = ":debug_keystore",
    deps = [
        ":app-lib",
    ],
)

Starlark:

android_binary(
    name = "app",
    manifest = "AndroidManifest.xml",
    keystore = ":debug_keystore",
    deps = [":app-lib"],
)

The syntax for defining build targets is similar between Buck and Starlark, with minor differences in formatting and structure. Both use a declarative approach to specify build configurations, making it relatively easy for developers familiar with one system to understand the other.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Starlark

Build status

Overview

Starlark (formerly known as Skylark) is a language intended for use as a configuration language. It was designed for the Bazel build system, but may be useful for other projects as well. This repository is where Starlark features are proposed, discussed, and specified. It contains information about the language, including the specification. There are multiple implementations of Starlark.

Starlark is a dialect of Python. Like Python, it is a dynamically typed language with high-level data types, first-class functions with lexical scope, and garbage collection. Independent Starlark threads execute in parallel, so Starlark workloads scale well on parallel machines. Starlark is a small and simple language with a familiar and highly readable syntax. You can use it as an expressive notation for structured data, defining functions to eliminate repetition, or you can use it to add scripting capabilities to an existing application.

A Starlark interpreter is typically embedded within a larger application, and the application may define additional domain-specific functions and data types beyond those provided by the core language. For example, Starlark was originally developed for the Bazel build tool. Bazel uses Starlark as the notation both for its BUILD files (like Makefiles, these declare the executables, libraries, and tests in a directory) and for its macro language, through which Bazel is extended with custom logic to support new languages and compilers.

Design Principles

  • Deterministic evaluation. Executing the same code twice will give the same results.
  • Hermetic execution. Execution cannot access the file system, network, system clock. It is safe to execute untrusted code.
  • Parallel evaluation. Modules can be loaded in parallel. To guarantee a thread-safe execution, shared data becomes immutable.
  • Simplicity. We try to limit the number of concepts needed to understand the code. Users should be able to quickly read and write code, even if they are not experts. The language should avoid pitfalls as much as possible.
  • Focus on tooling. We recognize that the source code will be read, analyzed, modified, by both humans and tools.
  • Python-like. Python is a widely used language. Keeping the language similar to Python can reduce the learning curve and make the semantics more obvious to users.

Tour

The code provides an example of the syntax of Starlark:

# Define a number
number = 18

# Define a dictionary
people = {
    "Alice": 22,
    "Bob": 40,
    "Charlie": 55,
    "Dave": 14,
}

names = ", ".join(people.keys())  # Alice, Bob, Charlie, Dave

# Define a function
def greet(name):
    """Return a greeting."""
    return "Hello {}!".format(name)

greeting = greet(names)

above30 = [name for name, age in people.items() if age >= 30]

print("{} people are above 30.".format(len(above30)))

def fizz_buzz(n):
    """Print Fizz Buzz numbers from 1 to n."""
    for i in range(1, n + 1):
        s = ""
        if i % 3 == 0:
            s += "Fizz"
        if i % 5 == 0:
            s += "Buzz"
        print(s if s else i)

fizz_buzz(20)

If you've ever used Python, this should look very familiar. In fact, the code above is also a valid Python code. Still, this short example shows most of the language. Starlark is indeed a very small language.

For more information, see:

Build API

The first use-case of the Starlark language is to describe builds: how to compile a C++ or a Scala library, how to build a project and its dependencies, how to run tests. Describing a build can be surprisingly complex, especially as a codebase mixes multiple languages and targets multiple platforms.

In the future, this repository will contain a complete description of the build API used in Bazel. The goal is to have a clear specification and precise semantics, in order to interoperate with other systems. Ideally, other tools will be able to understand the build API and take advantage of it.

Evolution

Read about the design process if you want to suggest improvements to the specification. Follow the mailing-list to discuss the evolution of Starlark.

Implementations, tools, and users

See the Starlark implementations, tools, and users page.