Question

One line of code seems misleading. What I meant was in the form of a for ( ; ; ) ;.

While trying out lambda expression, just for fun, I have coded the program below. What I did was to change the third expression of the for-loop, where usually ++i resides, into lambda function. The output is also shown. It's like an obfuscated code but it seems to do the work, anyway. I was wondering if it was possible to do it in similar way with Java.

for (int i=1; i<10; [](int i) {for (int j=2; j<10; ++j) printf("%dx%d=%2d ",j,i,i*j);}(i++)) printf("\n");

2x1= 2 3x1= 3 4x1= 4 5x1= 5 6x1= 6 7x1= 7 8x1= 8 9x1= 9 
2x2= 4 3x2= 6 4x2= 8 5x2=10 6x2=12 7x2=14 8x2=16 9x2=18 
2x3= 6 3x3= 9 4x3=12 5x3=15 6x3=18 7x3=21 8x3=24 9x3=27 
2x4= 8 3x4=12 4x4=16 5x4=20 6x4=24 7x4=28 8x4=32 9x4=36 
2x5=10 3x5=15 4x5=20 5x5=25 6x5=30 7x5=35 8x5=40 9x5=45 
2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 7x6=42 8x6=48 9x6=54 
2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 8x7=56 9x7=63 
2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 9x8=72 
2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 

For somewhat better readability, I've separated the for-loop elements and the lambda function.

for (int i=1; i<10; 
    [](int i) {
        for (int j=2; j<10; ++j) 
            printf("%dx%d=%2d ",j,i,i*j);
    } (i++)) 
{
    printf("\n");
}

I tried to insert the Java lambda function similar to C++ like (int i) -> {...} but it doesn't seem correct syntax for the Java for-loop.

I've got curious when I read this article. It's in Korean but the code listed are in C++ so I guess any one can read them. First comes some screen captures of a Korean drama I don't know of. The first picture shows Java code for the multiplication. It seems that one of the actor is telling the other guy that it could be done with one line of code.

The author of the article tries if it is possible in C++. He is using multiple printfs separated by commas in the for-loop statement. What I did was to make it a lambda function.

So, would it be possible to do it in a similar way with Java?

Was it helpful?

Solution

Well, I am answering my own question.

Unlike C++, Java seems strict about loop-control variable statements. Putting in lambda function in any form gives error.

So, what I did instead was to use single for-loop with two loop control variables, like this.

// Single for-loop
for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j)
    System.out.format("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' ');

Since it could be done the same with C++, I got curious and compared both methods in C++ source and their assembly code.

Here is the C++ code (indented for better readability but...), and

// 1. Using lambda function
for (int i=1; i<10; 
    [](int i) {for (int j=2; j<10; ++j) 
        printf("%dx%d=%2d ",j,i,i*j);}(i++)) 
    printf("\n");

// 2. Using single for-loop
for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j) 
    printf("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' ');

here is the assembly (NetBeans-MinGW gcc generated). The one with lambda function generates smaller code than the single for-loop with multiple ternary operators.

!    // 1. Using lambda function
!    for (int i=1; i<10; [](int i) {for (int j=2; j<10; ++j) printf("%dx%d=%2d ",j,i,i*j);}(i++)) printf("\n");
main(int, char**)()
main(int, char**)+22: movl   $0x1,-0xc(%ebp)
main(int, char**)+29: jmp    0x40172a <main(int, char**)+65>
main(int, char**)+31: movl   $0x40a06f,(%esp)
main(int, char**)+38: call   0x408248 <printf(char const*, ...)>
main(int, char**)+43: mov    -0xc(%ebp),%edx
main(int, char**)+46: incl   -0xc(%ebp)
main(int, char**)+49: lea    -0x15(%ebp),%eax
main(int, char**)+52: mov    %edx,(%esp)
main(int, char**)+55: mov    %eax,%ecx
main(int, char**)+57: call   0x4016a0 <operator()(int) const>
main(int, char**)+62: sub    $0x4,%esp
main(int, char**)+65: cmpl   $0x9,-0xc(%ebp)
main(int, char**)+69: setle  %al
main(int, char**)+72: test   %al,%al
main(int, char**)+74: jne    0x401708 <main(int, char**)+31>
!    
!    // 2. Using single for-loop
!    for (int i=1, j=2; i<10; i=(++j==10) ? i+1 : i, j=(j==10) ? 2 : j) printf("%dx%d=%2d%c",j,i,i*j,(j==9) ? '\n' : ' ');
main(int, char**)+76: movl   $0x1,-0x10(%ebp)
main(int, char**)+83: movl   $0x2,-0x14(%ebp)
main(int, char**)+90: jmp    0x4017a8 <main(int, char**)+191>
main(int, char**)+92: cmpl   $0x9,-0x14(%ebp)
main(int, char**)+96: jne    0x401752 <main(int, char**)+105>
main(int, char**)+98: mov    $0xa,%eax
main(int, char**)+103: jmp    0x401757 <main(int, char**)+110>
main(int, char**)+105: mov    $0x20,%eax
main(int, char**)+110: mov    -0x10(%ebp),%edx
main(int, char**)+113: imul   -0x14(%ebp),%edx
main(int, char**)+117: mov    %eax,0x10(%esp)
main(int, char**)+121: mov    %edx,0xc(%esp)
main(int, char**)+125: mov    -0x10(%ebp),%eax
main(int, char**)+128: mov    %eax,0x8(%esp)
main(int, char**)+132: mov    -0x14(%ebp),%eax
main(int, char**)+135: mov    %eax,0x4(%esp)
main(int, char**)+139: movl   $0x40a071,(%esp)
main(int, char**)+146: call   0x408248 <printf(char const*, ...)>
main(int, char**)+151: incl   -0x14(%ebp)
main(int, char**)+154: cmpl   $0xa,-0x14(%ebp)
main(int, char**)+158: jne    0x40178f <main(int, char**)+166>
main(int, char**)+160: mov    -0x10(%ebp),%eax
main(int, char**)+163: inc    %eax
main(int, char**)+164: jmp    0x401792 <main(int, char**)+169>
main(int, char**)+166: mov    -0x10(%ebp),%eax
main(int, char**)+169: mov    %eax,-0x10(%ebp)
main(int, char**)+172: cmpl   $0xa,-0x14(%ebp)
main(int, char**)+176: je     0x4017a0 <main(int, char**)+183>
main(int, char**)+178: mov    -0x14(%ebp),%eax
main(int, char**)+181: jmp    0x4017a5 <main(int, char**)+188>
main(int, char**)+183: mov    $0x2,%eax
main(int, char**)+188: mov    %eax,-0x14(%ebp)
main(int, char**)+191: cmpl   $0x9,-0x10(%ebp)
main(int, char**)+195: setle  %al
main(int, char**)+198: test   %al,%al
main(int, char**)+200: jne    0x401745 <main(int, char**)+92>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top