I have a proposal that we desugar if statements in the same manner as the desugaring of for does. This allows if to be customizable in the same way as for, which I think makes Scala more consistent.
if (condition) t else f
is desugared into
with cond having the following signature:
def cond[A](t: => A, f: => A): R
This might be useful in a few cases. E.g.:
Given a probability monad Stochastic[+_], and if we have a probabilistic Boolean, we could do
val coinFlip: Stochastic[Boolean]
val t: A
val f: A
val r: Stochastic[A] = if (coinFlip) t else f
This is more declarative for probabilistic programming than using a monadic comprehension:
val r = for (isObverse <- coinFlip) yield if (isObverse) t else f
Or in an autodiff system (i.e. deep learning) when we build a computation graph conditioned on the value of a variable:
val c: Symbolic[Boolean]
val t: Symbolic[A]
val f: Symbolic[A]
val r = Conditional(c, t, f)
// creates a conditional expression whose result depends on c at runtime
// compare `tf.cond` in TensorFlow and `torch.where` in PyTorch
We could make this into a more readable form:
val r = if (c) t else f
I agree that this is rather niche, but in my opinion would be a nice addition.
It’s a matter of compiler optimisation. You could still have a virtualised while that does not need to create a lambda when the receiver is Boolean. Wasn’t there a plan to optimise for for some cases (such as using a Range)? What happened to that?
If it is an actual Boolean in the if condition, I’m sure that the compiler can rewrite it to a simple JVM if. I guess that the same can be done for for (i <- x to y) (as for why it is not rewritten, I don’t know).