Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a short circuit 'or' that returns the first 'true' value?

Scheme has a short-circuiting or that will return the first non-false value:

> (or 10 20 30)
10
> (or #f 20 30)
20
> (or #f)
#f

It does not evaluate its arguments until needed.

Is there something like this already in PowerShell?

Here's an approximation of it:

function or ()
{
    foreach ($arg in $args) {
        $val = & $arg; if ($val) { $val; break }
    }
}

Example:

PS C:\> or { 10 } { 20 } { 30 }
10

Example:

PS C:\> $abc = $null

PS C:\> or { $abc } { 123 }
123

PS C:\> $abc = 456

PS C:\> or { $abc } { 123 }
456
like image 451
dharmatech Avatar asked Feb 23 '14 22:02

dharmatech


People also ask

What is short-circuit boolean evaluation?

Short-circuit evaluation, minimal evaluation, or McCarthy evaluation (after John McCarthy) is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first ...

Does Python all short-circuit?

Short-Circuiting in all() and any() Inbuilt functions all() and any() in python also support short-circuiting.

What does it mean for an IF statement to be short circuited?

Short-circuiting is where an expression is stopped being evaluated as soon as its outcome is determined. So for instance: if (a == b || c == d || e == f) { // Do something } If a == b is true, then c == d and e == f are never evaluated at all, because the expression's outcome has already been determined.

What is short-circuit OR jumping code?

Short-Circuit Evaluation: Short-circuiting is a programming concept in which the compiler skips the execution or evaluation of some sub-expressions in a logical expression. The compiler stops evaluating the further sub-expressions as soon as the value of the expression is determined.


3 Answers

You could do something like this:

10, $false, 20 | ? { $_ -ne $false } | select -First 1

The result is either the first value from the input list that isn't $false, or $null. Since $null is among the values that PowerShell treats as $false in comparisons, the above should do what you want.

like image 143
Ansgar Wiechers Avatar answered Oct 23 '22 22:10

Ansgar Wiechers


As far as I know, there isn't anything like this built in. I think your function looks pretty good.

It might be more idiomatic to make it take pipelined input:

function or
{
    foreach ($x in $input) {
        $val = & $x; if ($val) { $val; break }
    }
}

Example:

PS > $abc = $null
PS > { $abc },{ 123 } | or
123    
PS > $abc = 456
PS > { $abc },{ 123 } | or
456
like image 22
dan-gph Avatar answered Oct 23 '22 21:10

dan-gph


You're trying to make PowerShell use a Scheme-like syntax by way of your function. Don't do this. Write idiomatic PowerShell. Trying to coerce one language into looking like another language just makes things harder on yourself, introduces lots of room for bugs, and will confuse the %$^%&^*( out of whoever has to maintain your code after you're gone.

PowerShell does appear to short-circuit. Put this code in the ISE and set a breakpoint on the write-output lines in each function, then start the debugger (F5):

function first () {
    write-output "first"
}

function second() {
    write-output "second"
}

$true -or $(first) -or $(second);
$false -or $(first) -or $(second);
$false -or $(second) -or $(first);   

$true evaluates to true (obviously), so it doesn't attempt to process the expression beyond that point. When the next to last line processes, only the breakpoint in first processes. When the last line processes, only the breakpoint in second() is hit.

like image 3
alroc Avatar answered Oct 23 '22 21:10

alroc