Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutable "pipeline assignment" operator #14870

Open
NotTheDr01ds opened this issue Jan 20, 2025 · 5 comments
Open

Mutable "pipeline assignment" operator #14870

NotTheDr01ds opened this issue Jan 20, 2025 · 5 comments
Labels
enhancement New feature or request needs-triage An issue that hasn't had any proper look syntax Changes to the grammar or syntax beyond parser bugfixes

Comments

@NotTheDr01ds
Copy link
Contributor

NotTheDr01ds commented Jan 20, 2025

Related problem

I'm not sure if I have the naming right, but when dealing with config (or other mutable variables), the convenience of the += and ++= operators only goes so far. When dealing with, for instance, a record that needs a merge, you still have to resort to $variable = $variable | merge {}.

We currently have:

╭───┬──────────┬────────────────╮
│ # │ operator │      name      │
├───┼──────────┼────────────────┤
│ 0 │ +=       │ PlusAssign     │
│ 1 │ ++=      │ ConcatAssign   │
│ 2 │ -=       │ MinusAssign    │
│ 3 │ *=       │ MultiplyAssign │
│ 4 │ /=       │ DivideAssign   │
╰───┴──────────┴────────────────╯

Describe the solution you'd like

A PipeAssign operator, probably |= which would allow a RHS expression that would simply use the value of the LHS as pipeline input. For example:

mut foo = "foo"
$foo |= str upcase
$foo
# => FOO

This comes in handy with longer $env.config entries.

# Without operator:
$env.config.hooks.env_change = (
    $env.config.hooks.env_change
    | merge deep --strategy=append {
          PWD: [{|before,after| null }]
      }
)

# With operator
$env.config.hooks.env_change |= merge deep --strategy=append {
    PWD: [{|before,after| null }]
}

Describe alternatives you've considered

No response

Additional context and details

No response

@NotTheDr01ds NotTheDr01ds added enhancement New feature or request needs-triage An issue that hasn't had any proper look labels Jan 20, 2025
@sholderbach sholderbach added the syntax Changes to the grammar or syntax beyond parser bugfixes label Jan 20, 2025
@tmillr
Copy link
Contributor

tmillr commented Jan 20, 2025

I also mentioned this here: #14822

Also it shouldn't be too hard to implement.

I'd like to see this too (|=). And if that would only work with mut variables and env, then maybe it should work with let too:

let var |= ...

# Which is equal to:
let var = $var | ...

@NotTheDr01ds
Copy link
Contributor Author

@tmillr Agreed - "shadow assignment" operators would also be nice.

I've edited your list with a pointer here for "pipeline assignments", but if you want to enter a separate one for the "shadow assignments", to raise its visibility, that would be great.

@sholderbach
Copy link
Member

What is the semantics of

$foo |= bar | baz

And if we follow the assignment expression route is this disallowed?

bla | $foo |= bar | baz

@tmillr
Copy link
Contributor

tmillr commented Jan 31, 2025

What is the semantics of

$foo |= bar | baz

I'd say the same as $foo = $foo | bar | baz, which I believe itself is equivalent to $foo = ($foo | bar | baz)?

And if we follow the assignment expression route is this disallowed?

bla | $foo |= bar | baz

I would say disallowed. It should be $foo |= bla | bar | baz.


hmmm I didn't realize that piping directly into an assignment was legal. It's kinda unintuitive because let doesn't allow that. Is there a good reason to allow such a thing in any case? It only makes for confusing code imo. bla | $foo = bar | baz is always better written $foo = bla | bar | baz, and bla | $foo = bar $in | baz is better written as $foo = bar (bla) | baz or let var = bla; $foo = bar $var | baz.

@NotTheDr01ds
Copy link
Contributor Author

NotTheDr01ds commented Feb 1, 2025

$foo |= bar | baz

Agree with @tmillr - That would be:

$foo = ($foo | bar | baz)

And for ...

bla | $foo |= bar | baz

Today, any value piped into a mutable assignment is ignored unless $in is used, right?

mut a = 5
1000 | $a += 1
# => 6

1000 | $a += $in
# => 1006

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs-triage An issue that hasn't had any proper look syntax Changes to the grammar or syntax beyond parser bugfixes
Projects
None yet
Development

No branches or pull requests

3 participants