Translating source code into a different language as practice
One of the things I encourage my programming students to do is to take open source programs and rewriting them in a different programming language, or using a different GUI toolkit. There are a number of benefits to this:
- The student learns to read somebody else’s code
- The student learns to analyze code in a language that is different from the one they are learning
- The student (hopefully) learns a few new programming techniques along the way
- It is yet another way to keep the student writing code
- It provides a bit of variation from the old “write a program that..”-type exercises.
It’s easy to say that this is a “passive” process, meaning the student simply just translates the code to “their own” programming language without reflecting much about what they are doing. That may be true for some people, but then again, some people go through an entire programming class without reflecting much on what they are doing.
Another thing is that a friend of mine raised the concern that programming languages sometimes differ in techniques and that if I am translating a C program into Java I might be learning “C-isms”. First of all, I don’t quite understand what is so wrong with “C-isms”. Secondly, it is your responsibility as a teacher/mentor to review their code and point out areas where they could improve the program.
Remember that at first the student’s primary concern is with getting the program running at all. It is only once they have been able to do succeed in that that they will start worrying about “making it look like a conventional Java program”. The following might be a rough sketch of this process.
- Translate the program straight off (leaving variable names exactly the same etc). At this stage, the students only concern is to get the program to compile (in the case of a compiled language) and run, with all the functionality of the original program intact.
- Next they begin to do things like renaming variables to suit the language. For example, if translating a C program to Java, you might want to rename a variable from
x_axistoxAxissimply because that is a convention that most Java programmers follow. - Then the student refines the code. In the case of translating from a non-object orient language to an object oriented one, this might involve moving parts of the application functionality out into classes, where that makes sense.
Translating a program from for example C to Java, or from using Qt to using Gtk is not some form of miracle solution that will turn everybody into a master programmer. But it is a way to let the people who are genuinely interested in programming to get some extra practice. That’s all. I find the exercise useful. I would love to hear what others think. Please leave your comments/experiences in the comments section.
Finally I will give a small example. Recently, I had a Java student who said he wanted to learn how to do graphics programming. So I helped him get a hold of some programs (mostly in C) and told him to start translating them into Java. To demonstrate it I took this program by CorTeX/Optimum and wrote it as a Java applet. You can see the result below (you will obviously need to create an HTML document to load the applet in order to see it in action).
1 /*
2 * "Flashouillis" for Java.
3 *
4 * Original C program written by corTeX/Optimum.
5 *
6 * Author: Lorenzo E. Danielsson <danielsson.lorenzo (AT) gmail DOT com>
7 * Date created: 2007.04.21
8 */
9
10 import java.awt.Color;
11 import java.awt.Graphics;
12 import java.awt.Image;
13 import javax.swing.JApplet;
14
15 import static java.lang.Math.cos;
16 import static java.lang.Math.sin;
17 import static java.lang.Math.random;
18
19 public class JFlash extends JApplet implements Runnable {
20 private final int WIDTH = 500;
21 private final int HEIGHT = 500;
22 private final int DELAY = 10;
23 private final int FLASH_MAX = 5000; // Number of points.
24 private final int G_ACC = 330; // Acceleration (g).
25
26 private Thread animation = null; // Animation thread.
27 private Graphics buffer = null; // Back buffer for drawing.
28 private Image image = null;
29 private Flash[] flash = new Flash[FLASH_MAX];
30 private int current;
31 private float ax = 0.0F, ay = 0.0F, az = 0.0F;
32
33 public void init() {
34 image = createImage(WIDTH, HEIGHT);
35 buffer = image.getGraphics();
36
37 for (int i = 0; i < FLASH_MAX; ++i) {
38 flash[i] = new Flash();
39 flash[i].state = 0.0F;
40 }
41
42 current = 0;
43 }
44
45 public void paint(Graphics g) {
46 buffer.setColor(Color.BLACK);
47 buffer.fillRect(0, 0, WIDTH, HEIGHT);
48
49 for (int i = 0; i < FLASH_MAX; ++i) {
50 if (flash[i].state == 0 || flash[i].state >= 1)
51 continue;
52
53 int x = (int)(flash[i].x + flash[i].vx * flash[i].state);
54 int y = (int)(flash[i].y + flash[i].vy * flash[i].state
55 + (flash[i].state * flash[i].state) * G_ACC);
56
57 if (x < 0 || x > WIDTH || y < 0 || y > HEIGHT)
58 continue;
59
60 int red = (int)(flash[i].r * (1 - flash[i].state)) << 3;
61 int green = (int)(flash[i].g * (1 - flash[i].state)) << 2;
62 int blue = (int)(flash[i].b * (1 - flash[i].state)) << 3;
63
64 if (red > 255) flash[i].r = 255;
65 if (green > 255) flash[i].g = 255;
66 if (blue > 255) flash[i].b = 255;
67
68 buffer.setColor(new Color(red, green, blue));
69 buffer.drawLine(x, y, x, y);
70
71 flash[i].state += 0.007F;
72 }
73
74 g.drawImage(image, 0, 0, null);
75 }
76
77 public void run() {
78 Thread thread = Thread.currentThread();
79 while (animation == thread) {
80 repaint();
81
82 int x = (int)(WIDTH/2 + WIDTH/4 * (cos(ax+ay) + sin(ay-az)));
83 int y = (int)(HEIGHT/2 + HEIGHT/4 * (sin(ax-ay+2*az)
84 + sin(ax+ax/2)));
85
86 for (int j = 0; j < 40; ++j) {
87 float rd = (float)(2.0 * random() * Math.PI);
88 float vx = (float)(cos(rd));
89 float vy = (float)(sin(rd));
90 rd = (float)(50.0 + random() * 30.0);
91 vx *= rd;
92 vy *= rd;
93
94 flash[current].x = x + ((int)(random() * Integer.MAX_VALUE)
95 & 3);
96 flash[current].y = y + ((int)(random() * Integer.MAX_VALUE)
97 & 3);
98
99 flash[current].vx = vx;
100 flash[current].vy = vy;
101 flash[current].state = 0.01F;
102
103 flash[current].r = (int)(10 * cos(ax*6) + 20);
104 flash[current].g = (int)(20 * cos(ay*5) + 40);
105 flash[current].b = (int)(10 * cos(az*7) + 20);
106
107 ++current;
108 if (current == FLASH_MAX)
109 current = 0;
110 }
111
112 ax += 0.05F;
113 ay += 0.03F;
114 az += 0.0441F;
115
116 try {
117 thread.sleep(DELAY);
118 } catch (Exception e) {}
119 }
120 }
121
122 public void start() {
123 animation = new Thread(this);
124 if (animation != null)
125 animation.start();
126 }
127
128 public void stop() {
129 if (animation != null)
130 animation = null;
131 }
132
133 public void update(Graphics g) {
134 g.clipRect(0, 0, WIDTH, HEIGHT);
135 paint(g);
136 }
137 }
138
139 class Flash {
140 public int x = 0, y = 0;
141 public int r = 0, g = 0, b = 0;
142 public float state = 0.0F;
143 public float vx = 0.0F, vy = 0.0F;
144 }
145
So this obviously does quite a few things that look familiar to a C programmer but maybe less so to a person from a Java background. But the point is that Java does support the shift operators. I’m not sure if you gain anything performance-wise in Java by using the shift operators for multiplying and dividing, but it is not illegal to do so.
Now this is just a first iteration of the program. It works, and looks like the original when run. You could easily modify it to look “better” from a Java point of view.



wow, great post. I program java but I hardly do graphics and animation stuff. Nice post.
Well for me, when I want to a learn a new language, I normally rewrite a program I wrote in a language I’m comfortable with, with the new language I’m learning, that way it gives me firm understanding of the new language and let me experiment most features and its syntax. Translating source code from one language to another is really a good practice.
Comment by eyedol — 2007.06.23 @ 21:58
This website is Great! I will recommend you to all my friends. I found so much useful things here. Thank you.
Comment by Claudette — 2007.09.09 @ 00:13