いいえ、Javaにはユーザー定義メソッドの熱心な評価しかありません。ご存知のように、Javaの言語構造のいくつかは非厳密な評価を実装しています。その他には、、、が含まif
れ?:
ますwhile
。
私はかつて[1]、「遅延評価を行う」とはどういう意味かについて混乱があることを学びました[1]。まず、遅延評価とは、必要に応じた評価を意味します。Javaにはこのようなものはまったくありません。ただし、遅延評価の定義を緩めて名前による呼び出しの評価も含めるという一般的な傾向があります(私は個人的にはお勧めしません)。などの機能は&&
、必要性による呼び出しと名前による呼び出しの評価では区別できません。それは関係なく同じだろう、それは問題を曖昧にする。
この緩みを考慮に入れて、Javaが次のように遅延評価を行っていると主張することにより、さらに反論する人もいます。
interface Thunk<A> {
A value();
}
&&
次に、次のようにユーザー定義を記述します。
boolean and(boolean p, Thunk<Boolean> q) {
return p && q();
}
次に、これはJavaの評価が遅延していることを示しているという主張が提起されます。ただし、これは緩い意味でも遅延評価ではありません。boolean
ここでの際立った点は、Javaの型システムは型/Boolean
とを統合しないということThunk<Boolean>
です。一方を他方として使用しようとすると、タイプエラーが発生します。静的型システムがない場合でも、コードは失敗します。質問に答えるのは、この統一性の欠如(静的型付けかどうか)です。いいえ、Javaにはユーザー定義の遅延評価がありません。もちろん、上記のようにエミュレートすることもできますが、これは、turing-equivalentに続く興味深い観察ではありません。
and
Scalaなどの言語には、名前による呼び出しの評価があり、通常の関数と同等のユーザー定義関数を使用でき&&
ます(終了を考慮に入れます。[1]を参照)。
// note the => annotation on the second argument
def and(p: Boolean, q: => Boolean) =
p && q
これにより、次のことが可能になります。
def z: Boolean = z
val r: Boolean = and(false, z)
この短いプログラムスニペットは、値を指定することで終了することに注意してください。また、タイプの値を名前による呼び出しとして統合します。Boolean
したがって、遅延評価の緩い定義に同意する場合(そして、これもお勧めしません)、Scalaには遅延評価があると言うかもしれません。ここでは、良いコントラストとしてScalaを提供します。真の遅延評価(必要に応じて)については、Haskellを参照することをお勧めします。
お役に立てれば!
[1] http://blog.tmorris.net/posts/a-fling-with-lazy-evaluation/