Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

How to Port Goto Code to Java

Name: Anonymous 2014-02-09 16:44

Lets see how we can replace an ugly goto with an elegant structured programming constructs.

Given an unstructured loop

line1:
printf("Dijkstra sucks cocks in hell.\n");
goto line1;


Without sacrificing any expressiveness, we can refactor the above code into:

line = 0;
while (line++ > 0)
{
switch(line)
{
case 1: printf("Dijkstra sucks cocks in hell.\n") break;
case 2: line = 1; break;
}
}


Not only did we killed goto, but also gained a way to address lines of code dynamically. I.e. we can compute the next value of "line" variable.

Name: Anonymous 2014-02-09 16:51

Is this from an actual Java book? I wouldn't be impressed if it were.

Name: Anonymous 2014-02-09 16:51

uh what

Name: Anonymous 2014-02-09 17:18

Brilliant! Thanks for posting this, OP.

I also noticed something disturbing while testing this on some simple C code of mine: While scanning the source for those nasty goto statements, I noticed from analysis of intermediate output that many times my innocent, structured if statements were being silently transformed into goto directives by the compiler!

This was clearly unacceptable, but your fix saved the day.

From this:

static void fizzbuzz(int n)
{
int i;
for (i = 1; i < n; ++i) {
if ((i % 3 == 0) && !(i % 5 == 0)) {
printf("Fizz\n");
} else if (!(i % 3 == 0) && (i % 5 == 0)) {
printf("Buzz\n");
} else if ((i % 3 == 0) && (i % 5 == 0)) {
printf("Buzz\n");
} else if (!(i % 3 == 0) && !(i % 5 == 0)) {
printf("%d\n", i);
}
}
}


To THIS!!!

static void fizzbuzz(int n)
{
int line = 1;
int computed_line;
int i;
while (line < 200) {
switch (line) {
case 10: i = 0; break;
case 20: i = i + 1; break;
case 21: computed_line = 95; break;
case 30: if (i > n) line = 200; break;
case 40: if (i % 3 == 0) computed_line += 30; break;
case 50: if (i % 5 == 0) computed_line += 50; break;
case 60: line = computed_line; break;
case 100: printf("%d\n", i); line = 15; break;
case 130: printf("Fizz\n"); line=15; break;
case 150: printf("Buzz\n"); line=15; break;
case 180: printf("FizzBuzz\n"); line=15; break;
}

line++;
}
}


There are still if statements, and therefore still goto statements in the result, but they are safely and structurally bound by the beauty of the while-switch goto-cleansing DESIGN PATTERN!

Name: Anonymous 2014-02-09 17:19

It's funny because the dumbass stupid "refactoring" it actually as stupid as the original code.

Name: Anonymous 2014-02-09 17:42

>>5
It's funny because it doesn't work. line++>0 is false the first run through.

Name: Anonymous 2014-02-09 17:49

>>6
If it got past there, it would also spin endlessly on setting line1=1, not on the printf.

Name: Anonymous 2014-02-11 17:52

This is awesome!

bad

int password_correct = 0;
char big_enough_buffer[10];
do {
puts("enter password to continue");
gets(big_enough_buffer)
if (strcmp(big_enough_buffer, PASSWORD) == 0)
password_correct = 1
} while(!password_correct)


good

int line = 0;
int password_correct;
char big_enough_buf[10];
while (line++ < 200) {
switch (line) {
case 20: password_correct = 0; break;
case 30: puts("enter password to continue"); break;
case 40: gets(big_enough_buffer); break;
case 50: if (strcmp(big_enough_buffer, PASSWORD) != 0) line = 69; break;
case 60: password_correct = 1; break;
case 70: if (!password_correct) line = 29; break;
}
}


Oh boy! I've got an idea that might improve this! Check this out:


#define PROGRAM(CODE) \
int line = 0; \
while (line < 999999) { \
switch (line) { \
CODE \
} \
line++; \
}
#define LINE case
#define GOTO(LINE) line = (LINE-1);
#define ENDLINE ;break;


Pretty awesome, I know =)

To make things even more clear:

#defin DO :
#define PLEASE /* just to be polite */


Now we can do our above code like this:


int password_correct;
char big_enough_buf[10];
CODE(
LINE 10 PLEASE DO password_correct = 0 ENDLINE
LINE 20 PLEASE DO puts("enter password to continue") ENDLINE
LINE 30 PLEASE DO gets(big_enough_buffer) ENDLINE
LINE 40 PLEASE DO if (strcmp(big_enough_buffer, PASSWORD) != 0) GOTO(60) ENDLINE
LINE 50 PLEASE DO password_correct = 1 ENDLINE
LINE 60 PLEASE DO if (!password_correct) GOTO(20) ENDLINE


And all this clearness with no goto at all =)

Name: Anonymous 2014-02-14 15:39

>>8
LINE 50 PLEASE DO password_correct = 1 ENDLINE
reads like good old BASIC for Commodore 64

Name: Anonymous 2014-02-14 16:20

>>9
It also smacks of good, old-school INTERCAL.

Name: Anonymous 2014-03-14 1:42

>>10
INTERCAL
Is that like INTERPOL? Are they the international calculation/calibration police?

Name: Anonymous 2014-03-14 7:24

>>11
Wow, someone hasn't heard about INTERCAL? Here's a diagram which should make it all clear: https://upload.wikimedia.org/wikipedia/commons/4/41/INTERCAL_Circuitous_Diagram.svg

Name: Anonymous 2014-03-14 13:13

>>11-kun should get right on learning INTERCAL. It's poised to shift a few paradigms and make huge strides in mindshare: http://intercaloninterstates.org/

Name: Anonymous 2014-03-20 20:37

>>12
TO NEW YORK
TO NEW YORK
TO NEW YORK

concrete jungle where dreams are made, oh
There's nothing you can't do, now you're in New York

Name: Anonymous 2016-11-10 18:15

#include <stdio.h>
#define BE =
#define IS =
#define EQU ==
#define MOD %
#define BEGIN int
#define PROGRAM main() {
#define PLUS +
#define LET int
#define LINE(n) ;line##n:
#define IF if(
#define THEN )
#define GOTO(n) goto line##n
#define END return 0;}
#define PRINTN(n) printf("%d",n)
#define PRINTS(s) printf("%s",s)
#define NEWLINE printf("\n")
#define NOT(n) !(n)
#define OR ||

BEGIN PROGRAM
LINE(10) LET I BE 1
LINE(20) IF I EQU 101 THEN GOTO(130)
LINE(30) IF I MOD 3 EQU 0 THEN GOTO(70)
LINE(40) IF I MOD 5 EQU 0 THEN GOTO(90)
LINE(50) IF NOT(I MOD 5 EQU 0 OR I MOD 3 EQU 0) THEN PRINTN(I)
LINE(60) GOTO(100)
LINE(70) PRINTS("FIZZ")
LINE(80) GOTO(40)
LINE(90) PRINTS("BUZZ")
LINE(100) NEWLINE
LINE(110) I IS I PLUS 1
LINE(120) GOTO(20)
LINE(130) END

Don't change these.
Name: Email:
Entire Thread Thread List