I want to define my own C++-17-like if statement. (It's an exercise in metaprogramming.)
I easily could define:
inline def xif[T](inline cond: Boolean)(inline body: T) = if cond then body
and/or
def yif[T](cond: Boolean)(body: => T) = if cond then body
so that these three definitions output the same numbers:
def testxif =
for i <- 0 until 10 do
xif {val j = i*3; j%2==0} {println(i)}
def testyif =
for i <- 0 until 10 do
yif {val j = i*3; j%2==0} {println(i)}
def testif =
for i <- 0 until 10 do
if ({val j = i*3; j%2==0}) {println(i)}
It is remarkable that xif and if generate the same code, good job, Scala! (The inline parameter is indeed inlined, while the "by-name" parameter (marked with "equals-greater" =>) is invoked as a lambda.)
public void testxif() {
.MODULE$.until$extension(scala.Predef..MODULE$.intWrapper(0), 10).foreach((i) -> {
int j = i * 3;
if (j % 2 == 0) {
scala.Predef..MODULE$.println(BoxesRunTime.boxToInteger(i));
}
});
}
public void testyif() {
.MODULE$.until$extension(scala.Predef..MODULE$.intWrapper(0), 10).foreach((i) -> {
int j = i * 3;
this.yif(j % 2 == 0, () -> {
this.testyif$$anonfun$1$$anonfun$1(i);
return BoxedUnit.UNIT;
});
});
}
public void testif() {
.MODULE$.until$extension(scala.Predef..MODULE$.intWrapper(0), 10).foreach((i) -> {
int j = i * 3;
if (j % 2 == 0) {
scala.Predef..MODULE$.println(BoxesRunTime.boxToInteger(i));
}
});
}
private final void testyif$$anonfun$1$$anonfun$1(final int i$1) {
scala.Predef..MODULE$.println(BoxesRunTime.boxToInteger(i$1));
}
I could easily define ifElse, but this would be rather lame. I want an optional xelse part, probably on the next line.
And I want values defined in the if part to be visible in the then part. In C++ 17, we can write:
#include <stdio.h>
int main() {
for(int i=0; i<10; i++) {
if(int j=i*3; j%2==0) {
printf("%d %d\n",i,j);
}
}
}
(note that j is defined in the if part)
But in Scala 3 this does not work, neither with my current xif nor with the out-of-box if:
def testxif2 =
for i <- 0 until 10 do
xif {val j = i*3; j%2==0} {println(i + " " + j)}
// ^
// Not found: j
Questions:
Given all this Scala-3 metaprogramming,
- How do I implement an optional
elsepart? (Let us call itxelse) - How do I make the values defined in the
ifpart visible in thethenandelseparts?