Of course, commands with spaces in their names are defined in the same way:
```nu
def "custom command" [] {
"This is a custom command with a space in the name!"
}
```
## Parameters
### Multiple parameters
In the `def` command, the parameters are defined in a [`list`](./types_of_data.md#lists). This means that multiple parameters can be separated with spaces, commas, or line-breaks.
For example, here's a version of `greet` that accepts two names. Any of these three definitions will work:
```nu
# Spaces
def greet [name1 name2] {
$"Hello, ($name1) and ($name2)!"
}
# Commas
def greet [name1, name2] {
$"Hello, ($name1) and ($name2)!"
}
# Linebreaks
def greet [
name1
name2
] {
$"Hello, ($name1) and ($name2)!"
}
```
### Required positional parameters
The basic argument definitions used above are _positional_. The first argument passed into the `greet` command above is assigned to the `name1` parameter (and, as mentioned above, the `$name1` variable). The second argument becomes the `name2` parameter and the `$name2` variable.
By default, positional parameters are _required_. Using our previous definition of `greet` with two required, positional parameters:
```nu
def greet [name1, name2] {
$"Hello, ($name1) and ($name2)!"
}
greet Wei Mei
# => Hello, Wei and Mei!
greet Wei
# => Error: nu::parser::missing_positional
# =>
# => × Missing required positional argument.
# => ╭─[entry #1:1:10]
# => 1 │ greet Wei
# => ╰────
# => help: Usage: greet <name1> <name2> . Use `--help` for more information.
```
::: tip
Try typing a third name after this version of `greet`. Notice that the parser automatically detects the error and highlights the third argument as an error even before execution.
:::
### Optional Positional Parameters
We can define a positional parameter as optional by putting a question mark (`?`) after its name. For example:
```nu
def greet [name?: string] {
$"Hello, ($name | default 'You')"
}
greet
# => Hello, You
```
::: tip
Notice that the name used to access the variable does not include the `?`; only its definition in the command signature.
:::
When an optional parameter is not passed, its value in the command body is equal to `null`. The above example uses the `default` command to provide a default of "You" when `name` is `null`.
You could also compare the value directly:
```nu
def greet [name?: string] {
match $name {
null => "Hello! I don't know your name!"
_ => $"Hello, ($name)!"
}
}
greet
# => Hello! I don't know your name!
```
If required and optional positional parameters are used together, then the required parameters must appear in the definition first.
#### Parameters with a Default Value
You can also set a default value for the parameter when it is missing. Parameters with a default value are also optional when calling the command.
```nu
def greet [name = "Nushell"] {
$"Hello, ($name)!"
}
```
You can call this command either without the parameter or with a value to override the default value:
```nu
greet
# => Hello, Nushell!
greet world
# => Hello, World!
```
You can also combine a default value with a [type annotation](#parameter-types):
```nu
def congratulate [age: int = 18] {
$"Happy birthday! You are ($age) years old now!"
}
```
### Parameter Types
For each parameter, you can optionally define its type. For example, you can write the basic `greet` command as:
```nu
def greet [name: string] {
$"Hello, ($name)"
}
```
If a parameter is not type-annotated, Nushell will treat it as an [`any` type](./types_of_data.html#any). If you annotate a type on a parameter, Nushell will check its type when you call the function.
For example, let's say you wanted to only accept an `int` instead of a `string`:
```nu
def greet [name: int] {
$"hello ($name)"
}
greet World
```
If we try to run the above, Nushell will tell us that the types don't match:
```nu
Error: nu::parser::parse_mismatch
× Parse mismatch during operation.
╭─[entry #1:1:7]