5

This is a very odd, and quite specific question.

Ultimately I am trying to write a program convert that takes in java source, and transforms it such that it does not use (Among other things)

  • Arrays
  • Loops
  • User defined methods
  • If statements

This is a challenge that I set for myself, after my teacher told me that it was impossible to write a program without using these things.

I have most of these worked out, including function inlining and array substitution, however I cannot work out how to manage an if statement.

In C++ I'd use labels and gotos and maybe ?:, however Java does not support GOTO statements.

My question is this: Given a section of code,

if(CONDITION)
{
   //More code in here
}

How can transform it such that it is functionally the same, however does not use the if keyword. Note that loop structures are also out of the question.

Given this, it would be easy to create else and else if statements. However I am also unsure of how to create loops using this, as there is no GOTO statement and methods are out of the question.

Edit: Please note that switches are also not allowed, nor is recursion (Ruled out by the fact that you cannot define user methods, and a recursive main function wouldn't work with every program) The ?: operator does not work for all situations. AFAIK you cannot call a void function with ?: as it wants to assign a value as part of its operation.

These conditions come from the IB Computer Science SL requires course, I am taking HL and as a class we were laughing at the 'mastery' factors for SL which include 'if' statements (And if fact 3/15 of them are 'User defined methods with params and return types) The challenge is effectively to FAIL a mastery test in SL while still producing a program that functions correctly.

Answer: (By bdares)

String result = (CONDITION)?"0":"A";
try{
    Integer.parseInt(result);
    //Condition is true
} catch(NumberFormatException e){
    //Condition is false
}
James
  • 1,569
  • 10
  • 18
  • A loop using goto and labels is still a loop, it's just using another syntax. To truly get rid of loops, you need to unroll them, i.e. put the statements in the loop to be executed sequentially instead. Which will be impossible for infinite loops (e.g. `while (1)`.) – Some programmer dude Oct 31 '11 at 08:12
  • 1
    @JoachimPileborg not true; he's not ruling out using the loops of pre-written libraries, so he could (theoretically) write `java.util.Loop(myObject.class, 10);` if such a library existed. As it stands, he can hack a solution out of, say, Collection objects. –  Oct 31 '11 at 08:16
  • http://www.antiifcampaign.com/ however this is about improved OOP (removing strained, hidden logic nested as IFs through better design) – earcam Oct 31 '11 at 08:28

5 Answers5

2
if(A) {
    X();
}
else{
    Y();
}

can be converted to:

A?X():Y();

You can nest these all you want, or simply remove one side of the : and get a simple if. The conditionals are easy.

If you want it to work for void methods, here's a way:

String result = A?"0":"A";
try{
    Integer.parseInt(result);
    X();
} catch(NumberFormatException e){
    Y();
}
  • Well I can use LinkedLists instead of arrays too. And ?: cannot be used for complex if statements, without having to prefix every line with var = (condition) ? /*Call a function or something here*/ : var – James Oct 31 '11 at 08:04
  • he didn't rule out recursion. – stivlo Oct 31 '11 at 08:10
  • @stivlo I suppose not... if you're allowed to use "library functions" (I would assume SE6 or SE7), then there are plenty of ways to loop arbitrary code. I misinterpreted his restrictions. –  Oct 31 '11 at 08:13
  • Library functions are allowed, I have just thought of using iterators for loops, and creating a dummy collection to allow this. Also ?: cannot call functions that do return void. IE c ? a() : b(); will not compile – James Oct 31 '11 at 08:14
  • 1
    Sure it won't even compile, even if X() and Y() return an int, it won't compile, I tried it. -1 – stivlo Oct 31 '11 at 08:22
  • Even using a dummy value (which fixed the int case) won't extend to void. :) – James Oct 31 '11 at 08:25
  • Yes :D Actually that is the perfect bit of code. It allows an arbitrary amount of code inside the statements :D. Although before I mark it as answer, can you confirm that try{}catch{} statements can be nested? – James Oct 31 '11 at 08:45
  • definitely. I do (er, did...) it all the time because I've worked on web apps that conditionally make calls to different DBs.. –  Oct 31 '11 at 08:47
2

You can use the conditional operator and a switch:

switch( CONDITION ? 1 : 0 )
{
    case 1:
        //... true code
        break;
    case 0:
        //... false code
        break;
}

For the loops you can unroll your code to some predefined maximum and use labeled breaks to jump out of the unrolled code early based on some condition. You can use break to end any code block in Java not just loops.

The Java language has no goto but the Virtual Machine has it, so you could of course also generate JVM instructions directly although this would be not much different from a regular Java compiler which also translates all ifs an loops into jump instructions.

x4u
  • 13,877
  • 6
  • 48
  • 58
2

I'm not sure it's possible to write an entire useful program without using an if statement. However, I think what your teacher may be getting at is that you can write code to follow the same "logical" path by using a more object-oriented approach in place of an if statement. For example:

public interface Moveable {
  void move(int x, int y);
}

public class Ball implements Moveable {
  private int x;
  private int y;

  public void move(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

public class NullMoveable {
  public void move(int x, int y) {
    // Do nothing.
  }
}

... and then in your main application code:

Moveable mv = new NullMoveable();    
// Move object; don't care if it's a Ball or a NullMoveable
// so no need to explicitly check with an if-statement.
mv.move(10, 50);

The principle here is that the fewer possible paths there are in your code (due to if statements) the easier it is to test and maintain.

Adamski
  • 54,009
  • 15
  • 113
  • 152
  • I am familiar with OOP and am experienced with programming. However Java is far from my main language. As a side note the converter currently supports removing user classes and structs, no more OOP :) – James Oct 31 '11 at 08:10
0

In some cases, you can use bit manipulation. For example:

if(x > 0) // positive number
{
    isPositive = true;
}
else // negative number
{
    isPositive = flase;
}

is equivalent to:

isPositive = (x >> 31) == 0;

EDIT:

This is just an example, of course you can do much more complex bit manipulation with one statement instead of doing it using bunch of if statements.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • funny, you depend on the size of integer, when you can just write `isPositive = x > 0;` – stivlo Oct 31 '11 at 08:26
  • @stivlo This is just an example, of course you can do much more complex bit manipulation with one statement instead of doing it using bunch of if statements. – Eng.Fouad Oct 31 '11 at 08:29
0

If you were allowed to use anonymous inner classes (these probably classify as user-defined methods, but I'll let you be the judge):

if(COND) {
  X();
} else {
  Y();
}

becomes:

ifReplacement(COND, 
              new Runnable() { public void run() { X();}},
              new Runnable() { public void run() { Y();}});

with signature:

public static void ifReplacement(boolean condition,
                                 Runnable ifBranch,
                                 Runnable elseBranch)

Of course, JDK8 lambdas would make this much nicer:

ifReplacement(COND, ()->X(), ()->Y());