bazelbuild / starlark

Starlark Language
Apache License 2.0
2.44k stars 163 forks source link

Positional-only arguments #247

Open fmeum opened 1 year ago

fmeum commented 1 year ago

I believe that https://peps.python.org/pep-0570, which describes very simple syntax for positional-only arguments, would be very useful to have in Starlark.

It does enable one to write clean and robust helper functions such as def format_rule_call(kind, /, **attrs) or def replace_fields(struct, /, **replacements) without having to worry about the edge case where a keyword argument kind or struct is passed.

This can currently be worked around to some extent by giving the positional arguments an odd name (e.g. __kind), but that's confusing, not guaranteed not to conflict and at odds with style guides.

ndmitchell commented 1 year ago

Note that the highly related PEP 3102 keyword-only arguments * syntax is already supported by Rust Starlark - https://github.com/facebookexperimental/starlark-rust/blob/38f480935dcfaf2a26a7c8e56fa2adc053b37b97/starlark/src/syntax/dialect.rs. It would seem to make sense that if Starlark were extended, it was extended with both.

fmeum commented 1 year ago

Keyword-only arguments are also supported in Bazel's implementation of Starlark and, from what I can tell, frequently used, especially in the Starlarkification efforts.

Citing @laurentlb from https://bazelbuild.slack.com/archives/CDCEKVCHY/p1678902971702729?thread_ts=1678902446.157669&cid=CDCEKVCHY

This can be discussed, but I don't think the syntax is very readable or intuitive, or well known by users in general. I think we're likely to push back on this unless there's a clear need.

I agree that the syntax isn't well known and perhaps also not intuitive. But I would consider the concept to be both well-known and intuitive. In more detail:

  1. Many of the built-in methods, e.g. any or all, have positional-only arguments. Both from the point of view of consistency as well as mockability in tests, it seems like pure Starlark definitions of these methods should be able to have the same semantics.
  2. Positional-only arguments would mostly be used by Starlark library or ruleset authors to make functions safe to use by end users without surprising edge cases. That is, the audience that would benefit the most from this feature (users of the functions) are also the ones that are the least likely to read the implementation and be confused by the /.
  3. Since positional-only arguments only disallow unintended usages of functions and don't otherwise alter the behavior of the function, ignoring the / when mentally parsing a function definition is generally just fine.