language icon indicating copy to clipboard operation
language copied to clipboard

Pattern-esque syntax for terser named arguments/record fields

Open nex3 opened this issue 2 years ago • 5 comments

The pattern-matching syntax introduces the constructs :var foo and :foo to declare a variable whose name matches a field on the object being matched. The purpose of this is to reduce duplication, to users don't have to explicitly write foo: var foo.

I propose using this syntax as a way to reduce duplication when passing named arguments (or constructing records). Specifically, make foo(:argument) equivalent to foo(argument: argument). Similarly, record literals could be declared using (:field) instead of (field: field). This would help reduce duplication and ease acclimation to Dart for users coming from JS, which supports similar behavior when using maps as named arguments (in JS, foo({argument}) is equivalent to foo({argument: argument})).

nex3 avatar May 23 '23 01:05 nex3

It's definitely going to be briefer, and is likely to get used a lot.

We'd have to define which expressions counts as having a "name" that can be used as parameter/field name.

  • A plain identifier is a given.
  • A prefixed identifier too, like : prefix.varName or : Class.staticVarName (and : prefix.Class.staticVarName).
  • Then we might as well allow : expression.getterName in general, so any expression ending in .identifier.
  • And parenthisation should be safe, even if never necessary: : (expression.getterName)

Those are fairly safe. Then there are the more speculative ones:

  • :foo.v1 ?? bar.v1 - both have the same name, use that. Similar for ||, && and ?/:.
  • :foo.v1 ?? (throw "Nope") - only one branch has a name, use that.
  • :await v1 - the await doesn't have to affect the name, the name's meaning is likely to still apply.
  • Other prefix operators? : ! foo.hasBar - probably not useful since ! changes, flips, the meaning, so why should the name still match?
  • Increment operators: : ++varName, : varName++ can both work, the name and value still match conceptually.
  • Assignment : foo = 42. Probably too weird, even if there is a name right there.
  • But maybe :foo = bar using bar as the name (or whatever the name of the RHS expression is), and ignore the LHS.
  • No binary operators otherwise. Generally, we want expressions in tail-like position, so the "name of the expression" still corresponds to the value.
  • More?

lrhn avatar May 23 '23 22:05 lrhn

The analogous feature in JS only works for plain identifiers, but it would be pretty neat to be able to use at least expressions ending in .identifier. Most of the others seem confusingly weird to me.

nex3 avatar May 23 '23 23:05 nex3

I really like this idea. As @nex3 suggests, I'd probably want to stick to simple identifiers and maybe identifiers wrapped in prefix expressions (which we allow for patterns). Going beyond that gets weird fast.

munificent avatar Jun 15 '23 00:06 munificent

Terse bools would be nice too:

(+:foo, -:bar) => (foo: true, bar: false)

DerpMcDerp avatar May 20 '24 02:05 DerpMcDerp

Based on an internal discussion, I did a quick scrape of of a corpus of pub packages to see how often this feature might be useful. I only considered the simple version of the feature where the named argument expression needs to be a simple identifier (foo) and not a call chain that ends in a getter like other.stuff.foo.

Looking at all named arguments:

-- Named arg could use (6240345 total) --
5856229 ( 93.845%): No   ====================================================
 384116 (  6.155%): Yes  ====

Out of all named arguments, about 6% are an identifier expression where it's the same identifier as the argument name (foo: foo).

Looking at only named arguments where the expression is an identifier:

-- Identifier arg could use (663720 total) --
384116 ( 57.873%): Yes  ================================
279604 ( 42.127%): No   ========================

When the expression is a simple identifier, it's the same identifier as the argument name nearly half the time.

This seems fairly useful to me.

munificent avatar Sep 25 '25 01:09 munificent