2

When do I need to use the verb return in Powershell? My functions work even if I omit this. I have written a simple Powershell Function to clarify my question.

Works:

function Get-StringTime {

    (Get-Date).ToString("yyyyMMdd")

}

Also works:

function Get-StringTime {

    return (Get-Date).ToString("yyyyMMdd")

}
Gill-Bates
  • 559
  • 8
  • 22

2 Answers2

2

Is it safe to omit "return" in Powershell Functions?

If your function body only has a single control flow path, then yes!

The sample function you've shown has no branching (no if statements and no ternary statements), and thus satisfies the criteria above.

It's worth noting that PowerShell scripts and functions don't have well-defined return parameters, they simply just emit output zero or more times throughout their life-cycle - in sharp contrast to many other object-oriented languages that have a similar return keyword


When do I need to use the verb return in Powershell?

As alluded above, the return keyword is a so-called flow control statement, and you should use it whenever you want your function to return control to the caller.

As discussed above, the sample function you've shown has no branching and simply needs to return control to the caller after the first and only statement in it, so return doesn't make a difference.

Let's write a function that has a more complicated control flow:

function Get-Factorial {
  param([int]$N)

  if ($N -le 1) {
    1
  }
  else {
    $N * (Get-Factorial ($N - 1))
  }
}

This function recursively calculates the factorial (N! => 1 * 2 * ... * N) of a given integer.

Let's say we wanted to get rid of that last else block:

function Get-Factorial {
  param([int]$N)

  if ($N -le 1) {
    1
  }

  $N * (Get-Factorial ($N - 1))
}

But now we have a problem - Get-Factorial will now always call itself regardless of the current value, and we'll end up with a StackOverflowException!

Here's where we can now use return - to return in case we hit $N -le 1!

function Get-Factorial {
  param([int]$N)

  if ($N -le 1) {
    # now we won't recurse if we hit this if block
    return 1
  }

  # this code will only be reached when we haven't returned already
  $N * (Get-Factorial ($N - 1))
}

To summarise:

  • The return keyword is a flow control statement
  • Therefore: use it when you need to modify the control flow of your code
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
0

To complement Mathias' helpful answer with a conceptual summary:

  • The purpose of return is flow control:

    • It instantly exits the current function (or script file or script block) and returns control to the caller - as opposed to automatically returning when the end of the current function or script is reached.

    • It is therefore only ever needed for exiting the current scope prematurely.

  • It acts independently of PowerShell's output behavior ("return values"), but - as syntactic sugar - you may optionally use it to also write to the success output stream before returning; that is:

    return (Get-Date).ToString("yyyyMMdd")
    
    • is syntactic sugar for the following two separate statements:

       (Get-Date).ToString("yyyyMMdd") # *implicitly output* the result
       return                          # exit the scope.
      
    • return is therefore not needed to produce output (a "return value").

    • Conversely, when return is optionally used to produce output, be aware that it isn't guaranteed to be the only output, given that any preceding statements may have produced output too (either implicitly or via the (rarely needed) Write-Output cmdlet); that is:

       42                                      # *implicit output*
       return (Get-Date).ToString("yyyyMMdd")
      
      • produces two output objects: 42, and the result of the (Get-Date).ToString("yyyyMMdd") call.
    • For more information about PowerShell's implicit output behavior, see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775