Does Java have lazy evaluation?

后端 未结 9 1525
面向向阳花
面向向阳花 2020-12-03 16:44

I know that Java has smart/lazy evaluation in this case:

public boolean isTrue() {
    boolean a = false;
    boolean b = true;
    return b || (a &&         


        
相关标签:
9条回答
  • 2020-12-03 17:34

    No, Java has only eager evaluation for user-defined methods. Some of Java's language constructs implement non-strict evaluation as you note. Others include if, ?:, while.

    I once learned[1] that there is some confusion around what it means to "have lazy evaluation." First, lazy evaluation means call-by-need evaluation. Java has nothing at all like this. However, there is a common trend (which I personally discourage) to loosen the definition of lazy evaluation to also include call-by-name evaluation. Functions such as && cannot be distinguished under call-by-need versus call-by-name evaluation; it would be the same regardless, which obscures the matter.

    Taking this loosening into account, some further counter-argue by claiming Java has lazy evaluation by the following:

    interface Thunk<A> {
      A value();
    }
    

    Then, you might write a user-defined && like so:

    boolean and(boolean p, Thunk<Boolean> q) {
      return p && q();
    }
    

    The claim is then put forward that this demonstrates that Java has lazy evaluation. However, this is not lazy evaluation, even in the loose sense. The distinguishing point here is that Java's type system does not unify the types boolean/Boolean and Thunk<Boolean>. Attempting to use one as the other will result in a type-error. In the absence of a static type system, the code would still fail. It is this lack of unification (static typing or not) that answers the question; no, Java does not have user-defined lazy evaluation. Of course, it can be emulated as above, but this is an uninteresting observation which follows from turing-equivalence.

    A language such as Scala has call-by-name evaluation, which allows a user-defined and function which is equivalent to the regular && function (taking termination into account. See [1]).

    // note the => annotation on the second argument
    def and(p: Boolean, q: => Boolean) =
      p && q
    

    This allows:

    def z: Boolean = z
    val r: Boolean = and(false, z)
    

    Note that this short program snippet terminates by providing a value. It also unifies values of type Boolean as call-by-name. Therefore, if you subscribe to the loose definition of lazy evaluation (and again, I discourage this), you might say that Scala has lazy evaluation. I provide Scala here as a good contrast. I recommend looking at Haskell for true lazy evaluation (call-by-need).

    Hope this helps!

    [1] http://blog.tmorris.net/posts/a-fling-with-lazy-evaluation/

    0 讨论(0)
  • 2020-12-03 17:36

    For simplicity you can use the Supplier interface from java 8 like this:

    Supplier<SomeVal> someValSupplier = () -> getSomeValLazily();
    

    Then in code afterwards you can have:

    if (iAmLazy) 
      someVal = someValSupplier.get(); // lazy getting the value
    else 
      someVal = getSomeVal(); // non lazy getting the value
    
    0 讨论(0)
  • 2020-12-03 17:38

    In Java (and other C-like languages), this is referred to as short-circuit evaluation.*

    And yes, in the second example isATrue is always called. That is, unless the compiler/JVM can determine that it has no observable side-effects, in which case it may choose to optimize, but in which case you wouldn't notice the difference anyway.


    * The two are quite distinct; the former is essentially an optimization technique, whereas the second is mandated by the language and can affect observable program behaviour.

    I originally suggested that this was quite distinct from lazy evaluation, but as @Ingo points out in comments below, that's a dubious assertion. One may view the short-circuit operators in Java as a very limited application of lazy evaluation.

    However, when functional languages mandate lazy-evaluation semantics, it's usually for a quite different reason, namely prevention of infinite (or at least, excessive) recursion.

    0 讨论(0)
提交回复
热议问题