Skip to content

feat: add f-string literals (f"…{expr}…") to Starlark#625

Open
IgorShishkin12 wants to merge 23 commits into
google:masterfrom
IgorShishkin12:master
Open

feat: add f-string literals (f"…{expr}…") to Starlark#625
IgorShishkin12 wants to merge 23 commits into
google:masterfrom
IgorShishkin12:master

Conversation

@IgorShishkin12
Copy link
Copy Markdown

This change implements Python-style f-string literals for Starlark.
An f-string such as f"hello {name}" is parsed as a single expression that evaluates to the string "hello Starlark" when name = "Starlark".
Only the interpolation syntax {expr} is supported; conversion flags (!r, !s), format specifiers (:>10, :.2f) and the raw+f combination (rf"…") are left for future work.

Reasoning:

  • Ergonomics: String concatenation or .format() calls are noisy and error-prone.
  • Familiarity: Every Python programmer already knows the syntax; no new learning curve for the dominant Starlark user base (Bazel, Buck, Tilt, etc.).
  • Performance : One parse-time rewrite plus a single format call is faster than creating intermediate strings for each + operator, and it avoids the temporary allocations that show up in macro-generated code.
  • Future-proofing: The groundwork (scanner, parser, resolver) is now in place. Conversion flags (!r, !s) and format specifiers (:>10) can be added later without breaking existing programs.

What is new:

  • Scanner: recognises f'…', f"…", f'''…''', f"""…""".
  • Parser: builds an FStringExpr node that keeps the literal segments and the interpolated expressions.
  • Resolver: visits the interpolated expressions.
  • Compiler: emits code that at runtime concatenates the literal parts and the evaluated expressions via the built-in format method (same strategy Python uses).
  • Tests: extensive unit tests for scanner, parser, resolver and end-to-end execution; golden-file test-suite in testdata/fstring.star.

Breaking changes:
None – f-strings are purely additive.

Implementation notes:

  • fcomp.args signature changed from (*syntax.CallExpr) to []syntax.Expr so it can be re-used for the implicit format call generated by f-strings.
  • The scanner uses a small stack to handle nested braces and triple quotes correctly. It is impossible to not use it if we want to allow nested fstrings.

Future work (not in this PR)

  • Support !r, !s, :fmt conversion / format specs.
  • Better error messages for unbalanced braces.
  • Disallow rf"…" combination.

@adonovan
Copy link
Copy Markdown
Collaborator

Thanks for contributing to Starlark. If you haven't already, please do read the Contributing section of the project home page:

We welcome submissions but please let us know what you're working on if you want to change or add to the Starlark repository.

Before undertaking to write something new for the Starlark project, please file an issue or claim an existing issue. All significant changes to the language or to the interpreter's Go API must be discussed before they can be accepted. This gives all participants a chance to validate the design and to avoid duplication of effort.

Despite some differences, the Go implementation of Starlark strives to match the behavior of the Java implementation used by Bazel and maintained by the Bazel team. For that reason, proposals to change the language itself should generally be directed to the Starlark site, not to the maintainers of this project. Only once there is consensus that a language change is desirable may its Go implementation proceed.

There is an open spec issue for improved string formatting support at bazelbuild/starlark#91. We should establish a consensus there before committing to any particular implementation, though I'm sure your experience developing this PR will have given you valuable insights on how that issue should be decided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants