nushell icon indicating copy to clipboard operation
nushell copied to clipboard

"Return into pipe" is allowed but doesn't use the pipe

Open ThinkChaos opened this issue 1 year ago • 5 comments

Describe the bug

The precedence of command vs pipe causes return x | y to bypass | y, which is un-intuitive IMO, even if it does what's written on the tin!
Ideally I'd love it to be special cased so it's equivalent to return (x | y).

Alternatively, nu could warn or even fail to compile because that's always a user mistake.

How to reproduce

use std assert

def oops [] {
  return "something" | str replace "some" "no"
}

def main [] {
  assert equal (oops) "nothing"
}

Expected behavior

Pass the above test, or produce an explicit warning/compile error.

Screenshots

No response

Configuration

key value
version 0.95.0
major 0
minor 95
patch 0
branch
commit_hash
build_os linux-x86_64
build_target x86_64-unknown-linux-gnu
rust_version rustc 1.78.0 (9b00956e5 2024-04-29) (built from a source tarball)
cargo_version cargo 1.78.0
build_time 1980-01-01 00:00:00 +00:00
build_rust_channel release
allocator mimalloc
features default, sqlite, system-clipboard, trash
installed_plugins

Additional context

No response

ThinkChaos avatar Aug 19 '24 23:08 ThinkChaos

Everyone has a different opinion on what "intuitive" means. Traditionally in nushell ( and ) mean to evaluate whatever is between them. So, for me, return x | y is not as intuitive as return (x | y) is.

However, we've recently changed a few things where variables can be assigned like let a = ls | get name and while not as intuitive (to me), it is easier to type.

fdncred avatar Aug 19 '24 23:08 fdncred

Yeah I get that it's a preference thing which is why I also wrote that a warning/compile error seems acceptable to me.

But I didn't know let was changed like that. Do you know the PR by any chance? ~I didn't find it.~ I believe it's #13385

ThinkChaos avatar Aug 19 '24 23:08 ThinkChaos

Also it might be worth looking into other spots that could use a similar change.
For instance for it in a | b { } fails with help: 'for' keyword is not allowed in pipeline. Use 'for' by itself, outside of a pipeline, but it could just work.

ThinkChaos avatar Aug 19 '24 23:08 ThinkChaos

Do you know the PR by any chance?

#13385 changed $env.blah = blah and const a = b. I think let and mut were in another PR a while ago.

For instance for it in a | b { } ...

I'm not inclined to change this really. for x in (ls | get name) { } is how it's meant to be used. Others may feel differently.

fdncred avatar Aug 20 '24 00:08 fdncred

I am in the pro-parenthesis camp, not just to make sure things are more readable, but also to leave a certain margin for the inevitable typos and mistakes. Among the special characters out there (/) also tend to be among the most accessible ones across different keyboards.

The for loop example would become undecidable to parse

for it in ls | each { foo } | bar { baz } | blub { qux }

(taking into account the signature for a primitive like for would be incredibly stupid as this would mean the tree-sitter grammar in your editor couldn't work anymore and if bar had an optional closure argument for example, which block refers to the for is completely in the air)

sholderbach avatar Aug 20 '24 11:08 sholderbach

Just ran into this today. This is very confusing. Same issue with print. It just prints the first argument and the entire following pipe is dismissed, without saying a word. This should perhaps become a parse-time error.

theAkito avatar Mar 20 '25 15:03 theAkito