We want to define two functions, and() and or(), behaving like && and ||. Remember that they are so called short-circuit operators. We don't need to check the && second operand when the first is false. Similarly the for ||, when the first operand is true.
Let's express our requirements with assertions:
assert(and(false, false) == (false && false)) assert(and(false, true) == (false && true)) assert(and(true, false) == (true && false)) assert(and(true, true) == (true && true)) assert(or(false, false) == (false || false)) assert(or(false, true) == (false || true)) assert(or(true, false) == (true || false)) assert(or(true, true) == (true || true))Here is how I have implemented the two functions:
def and(a: Boolean, b: => Boolean) = if(a) b else false def or(a: Boolean, b: => Boolean) = if(a) a else bAND is implemented checking the first parameter. If it is true I need to check the second one, otherwise the resulting value is false. Dually for OR, if the first parameter is true, that is the result, otherwise it depends on the second one.
Notice that in both function I have specified that the second parameter is subject to a by-name evaluation. This follows from the short-circuit property of the logical expressions. We can see how this is useful when the second parameter is expensive to evaluate. Or even an infinite loop, as here below:
def silly() : Boolean = silly assert(and(false, silly) == (false && silly)) assert(or(true, silly) == (true || silly))The short-circuit logic is implemented also from my functions, so no need of evaluating silly().
Obviously, if I pass silly() as first parameter to either and() or or(), I enter in an infinite loop, and I should kill my Scala application.
No comments:
Post a Comment