def make-list [val?: string] {
["f1" "f2"]
}
def use-list [list: list] {
$list | each { |it| $it + "!" }
}
let $val = "abc"
let $l = (make-list $val)
use-list $l
In this code, I have two functions, one to make a list, and another to consume that list. For the purposes of this MRE, make-list returns a simple hard-coded list, and use-list prints each element with an exclamation mark added to the end.
If this script executes correctly, it should print a list with two elements "f1!" and "f2!".
make-list has an optional parameter. In the code above, I create a $val variable, then pass that into make-list, and store the result of the pipeline to $l. Executing $l | describe instead of use-list $l prints list<string>, so I'm confident that $l is indeed a list.
The code above throws the following compile error:
Error: nu::parser::type_mismatch (link)
× Type mismatch.
╭─[/.../test.nu:10:1]
10 │ let $l = (make-list $val)
11 │ use-list $l
· ─┬
· ╰── expected List(Any), found String
╰────
However, I can modify the let $l ... line to allow the script to compile and execute correctly. Both of these options will allow the script to compile and returns the expected result.
- The parameter for
make-listcan be removed (because the parameter is optional).let $l = (make-list) - The parameter for
make-listcan be replaced by a string literallet $l = (make-list "abc")
I don't understand why using a variable as a parameter call is suddenly causing a type issue with the use-list function call. What am I doing wrong here?
As an interesting side note, and this might explain the "...found String" part of the error message, if I change the make-list parameter to an int:
def make-list [val?: int] {
["f1" "f2"]
}
# ...
let $val = 3
let $l = (make-list $val)
use-list $l
It will fail to compile with the same kind of error, but the "found" type will reflect the updated parameter type.
Error: nu::parser::type_mismatch (link)
× Type mismatch.
╭─[/.../test.nu:10:1]
10 │ let $l = (make-list $val)
11 │ use-list $l
· ─┬
· ╰── expected List(Any), found Int
╰────
Tested using Nushell version 0.74.0 and 0.75.0 on Arch Linux and Windows 11, respectively.
Something seems to "go wrong" with the variable binding. Your scenario does work if the literal string is being evaluated in a subexpression before it is being bound:
Even a seemingly useless type casting later on does the trick:
This is also consistent with other types. Adapting your
intexample:Likewise, having a
doclosure, or type-casting usinginto int, do work as well.Not of importance, however, is the syntax of the variable binding. With the
$sign omitted, all examples from above still work or fail under the same circumstances, e.g.:As expected, using
let l =instead oflet $l =also yields the same results.