Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a logic intensive algorithm that I need to code in two languages (actually I finished it in one language satisfactorily and am about to start coding in the other language). By logic intensive I mean the algorithm is non trivial, needs careful understanding and, importantly, could be having bugs (due to complexity and carelessness, you know) that would have to be patched in the future.

Also, I want to make sure that when this code changes hands, eventually, it must not overwhelm the new programmers.

Given this scenario, what are some ways that would help maintain the codebases and keep they in sync? By ways I mean software tools, best practices etc.

FYI the two languages are C++ and Java. C++ for Windows/Linux and Java for "everything else" including Android.

share|improve this question
2  
Do you really have to re implement it in another language? Why not use just Java? –  Oleksi May 26 '12 at 18:16
    
@Oleksi The code is best when it runs natively so Java was just a compromise where C++ can't be used. –  thePetProjectProgrammer May 26 '12 at 18:22
8  
Just make absolutely sure that you need that performance. Maintaining two versions of a program (especially one this complex), is a colossale effort. Make sure you absolutely need to do this in C++, because your are going to pay a huge cost in time and effort to do this in two languages. –  Oleksi May 26 '12 at 18:25
7  
As @Oleksi said - if it runs acceptably in Java on a Driod, I cannot imagine that as PC needs the (probably marginal) improvements C++ will give. As you have not stated you have run performance tests, I assume not, in which case this stinks of premature optimisation. Write in Java, run performance tests, optimise the Java. Only then consider a C++ rewrite - the time saved maintaining one code base, put into optimaisation instead, will almost certainly out perform maintaining two code bases, two sets of everything (except requirements). –  mattnz May 27 '12 at 1:42
    
@thePrivateProject define runs best, in either case (C++ or Java) well written code should be portable. –  Jarrod Roberson May 29 '12 at 15:39

7 Answers 7

up vote 10 down vote accepted

Short answer: don't do this unless absolutely forced.

If you have to use C++, then you might consider using the NDK to build your algorithm for Android in C++ and then add on a thin Java wrapper for the UI. Note that using the NDK means that your code is a lot less portable to different sorts of hardware. This is definitely not preferable to using Java everywhere, but better than having two code bases.

If you absolutely can't do this, and have to have two code bases, here are three suggestions:

1) Look for a tool like Unity geared towards portable software.

2) Try to pull the complex bits of the code into data, or some scripting language. If you can write fairly generic code to deal with the scripting language, it is easier to test and get right twice. (Especially if it is a standard language created by someone else.) Then you can have one codebase for the complex bits. (You might try Lua, which is geared towards embeddability.)

3) As the other answer states, create a test suite to validate both code sets. Note that this is really hard to get right. Having done exactly this, I can tell you that it leeds to lots of debates about which version is "right", especially in error cases.

(2) and (3) can be used together.

share|improve this answer
3  
Good points. Another thing to think about is writing one set of regression tests and testing both implementations with it (e.g. via SWIG). –  James Youngman May 27 '12 at 0:14

Build a single external test suite that can ensure both code bases behave the same way. I put extra emphasis on the word "single" because otherwise you will have to maintain two test suites which can differ in their assertions. I don't have any suggestions on how to do this, but it seems like one way to maintain your (and future developers') sanity when working on this kind of code base.

share|improve this answer

you could use a language that can compile into machine code and java byte code either by first transforming into java and C++ or directly. Last I checked LLVM has back-ends for both

edit: a bit of wiki surfing got me to GCJ which can compile java to machine code

share|improve this answer

In my opinion, the most important rule for a programmer is, "Don't Repeat Yourself". What you suggest is a clear violation of this rule.

I would seriously suggest that you find a way to only implement the algorithm once. I can currently think of two different approaches.

  • Use a domain specific language. Maybe the algorithm can be better expressed in a different language, e.g. a script language, for which a parser could exist on all the platforms you expect to run the application on, or you could generate C++/Java code based on the DSL code.

  • Write everything in C++. C++ can be compiled to virtually any platform. If on some platforms you require the main application to be written in Java, I would guess that it is possible to call a native library (I am not very knowledgeable in Java, but I assume that it can be done).

Maintaining the same algorithm on two different platforms can only lead to pain and bugs.

share|improve this answer
    
I suppose by your opinion there should be one operating system, on office productivity suit, one video player software package........ –  mattnz May 27 '12 at 1:34
1  
@mattnz - You have utterly misunderstood my point. I'm referring to the programming principle of "DRY". That principle does in no way suggest that there should be only one operating system, office suite, etc. You can easily produce a product for multiple platforms while sticking to DRY. –  Pete May 28 '12 at 16:32

In addition to the excelent advice to use a common external test suite you may want to look into literate programming. Literate programming tools give you the ability to produce multiple files from a single source file.

The traditional use of LP is to allow you to interleave documentation with code in a manner which allows you to keep the documentation very close to the source code. A single noweb file (for example) could be used to generate a documenation file which could be compiled into a larger document using (say) LaTex, and produce a .cpp and .h file which could be compiled into your application.

In your case, it could allow you to keep both code bases and documentation together, producing a .java file too.

Keeping the documentation and different code versions together in a single file, broken up into logically equivalent sections, should make it much easier to keep them all in sync with each other.

share|improve this answer

This is a good example of where tests can be helpful.

I would suggest having a single test suite that both your code base run against. Then you know that your code bases both conform to the same specification!

(and, have good test coverage!)

share|improve this answer

Disclaimer

As mentioned in previous, posts, if you don't really have another choice, then.

Answer

Several practical suggestions, instead of a single answer:

(1) Use common structures, even, if the same stuff can be done different.

Example: I had to have the same code in "Object Pascal" & "C++", where the "if" sentence exists in both, the parenthesis in "C++" is required, but, not in "object Pascal".

// Object Pascal
...
if MyBollExpression
begin
  ...
end;
...

// C++
...
if (MyBollExpression)
{
  ...
}
...

Changed to:

// Object Pascal
...
if (MyBollExpression)
begin
  ...
end;
...

// C++
...
if (MyBollExpression)
{
  ...
}
...

Added parenthesis to both languages. Another case will be optional namespaces versus required namespaces ( "packages" ).

(3) Keep identifiers names, case sensitiveness, specially types, similar, use aliases, subclassing, wrapping:

// Java
// 
import java.io.*;

...
System.out("Hello World\n");
...

// C++
// 
include <iostream>

...
cout << "Hello World\n";
...

Into:

// Java
// 
import java.io.*;

static class ConsoleOut
{
   void Out(string Msg)
   {
     System.out("Hello World\n");
   }
}

...
ConsoleOut MyConsole = new ConsoleOut();
...
MyConsole.out("Hello World\n");
...

// C++
// 
include <iostream>

public class ConsoleOut
{
   void Out(string Msg)
   {
     cout << "Hello World\n";
   }
}

...
ConsoleOut MyConsole = new ConsoleOut();
...
MyConsole.out("Hello World\n");

...

Summary

I usually have to work with several programming languages, and there are some custom "core" libraries, that I keep in several programming languages.

Good Luck.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.