Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Short circuit evaluation in Go

My understanding of short circuit evaluation is that an expression is only called when needed in an if statement. Does Go follow this?

For instance, would I get better performance on average from:

if !isValidQueryParams(&queries) || r == nil || len(queries) == 0 {
    return "", fmt.Errorf("invalid querystring")
}

...to this:

if r == nil || len(queries) == 0 || !isValidQueryParams(&queries) {
    return "", fmt.Errorf("invalid querystring")
}

...since isValidQueryParams is a function with much more overhead than r == nil or testing the length of a map?

i.e. will the interpreter evaluate r == nil first, see it's true and not bother to evaluate the other conditions?

EDIT: Incorrectly referred to short circuit evaluation as lazy evaluation

like image 703
stizzo96 Avatar asked Dec 11 '18 10:12

stizzo96


People also ask

What is short-circuit evaluation?

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.

Does Ada have short-circuit evaluation?

In programming languages with lazy evaluation (Lisp, Perl, Haskell), the usual Boolean operators are short-circuit. In others (Ada, Java, Delphi), both short-circuit and standard Boolean operators are available.

What does short-circuit evaluation mean for the || operator?

Short circuiting is an alternative way of using the logical AND or OR operators (& or |) e.g. a non short-circuit OR if(false | true) { } The first condition and second condition are both evaluated even if false is not true (which it always is). However it is was written as a short-circuit OR: if(false || true) { }

Does && use short-circuit evaluation?

Java's && and || operators use short circuit evaluation.


2 Answers

Thank you to Kostix and mkrieger for their answers - they are correct, I'm referring to short circuit evaluation and not lazy evaluation.

Go does implement normal short circuit evaluation, as can be deduced with the following code:

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        if testFunc(1) || testFunc(2) {
            // do nothing
        }
    }
}

func testFunc(i int) bool {
    fmt.Printf("function %d called\n", i)
    return true
}

...which will always give:

$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
like image 80
stizzo96 Avatar answered Oct 08 '22 06:10

stizzo96


This is called short circuit evaluation. According to this tutorial, the boolean operators use this:

Although in the Go language specification it does not explicitly state that Go uses short circuit evaluation, it does mention that

Logical operators apply to boolean values and yield a result of the same type as the operands. The right operand is evaluated conditionally.

Here is a quick example to prove that Go uses short circuit evaluation

[…]

like image 39
mkrieger1 Avatar answered Oct 08 '22 05:10

mkrieger1