1

I'm planning to write a single API that is syntactically valid in most major programming languages (to the greatest extent possible, so that only minimal amounts of code will need to be re-written when moving from one language to another). I think the simplest way to do this would be to write a group of functions that consisted entirely of function calls and variable assignments, since the syntax for function calls is almost exactly the same in all major programming languages.

Of course, I'd need to write "wrapper" functions for if-statements and while-loops, since the syntax of each of these is different in each programming language.

Here's a proof-of-concept for one "polyglot" function that should work in most programming languages:

//JavaScript syntax
function proofOfConcept(){
    printSomething("This is just a proof of concept."); //the function printSomething will
    //                      need to be implemented separately in each programming language.
}

//Java syntax
public static void proofOfConcept(){
    printSomething("This is just a proof of concept."); //the function printSomething will
    //                      need to be implemented separately in each programming language.
}

//Python syntax
def proofOfConcept():
    printSomething("This is just a proof of concept."); //the function printSomething will
    //                      need to be implemented separately in each programming language.

//C syntax
void proofOfConcept(){
    printSomething("This is just a proof of concept."); //the function printSomething will
    //                      need to be implemented separately in each programming language.
}

Would this be a useful design strategy, or is there a better way to do this? I think this would be a useful strategy for developing libraries in multiple programming languages, althogh it would require a small number of "language-specific" functions to be written for each target language.

Anderson Green
  • 563
  • 6
  • 13
  • 3
    I'm not sure why this would be helpful. Can you describe the problem you're trying to solve? – ipaul Mar 18 '13 at 02:47
  • @ipaul I'm trying to write an API that will be compatible with as many programming languages as possible. Of course, it would be necessary to write a few "language-specific" functions to handle if-statments and while-loops, and then write an entire function for the body of each while-loop and if-statement. – Anderson Green Mar 18 '13 at 02:47
  • 3
    http://www.infoq.com/articles/API-Design-Joshua-Bloch; "it is almost always wrong to transliterate an API from one platform to another" – Ismail Badawi Mar 18 '13 at 02:49
  • 2
    Ah, okay. Normally, this is done by picking one language in which to implement (i.e. C) and then using tools like SWiG to bang out interfaces that call the C code from other languages. As someone using your library I should care that you have a method called 'proofOfConcept' but I shouldn't care how you chose to implement it. – ipaul Mar 18 '13 at 02:50
  • @ipaul In C, I would implement `printSomething` as printf(thingToPrint). In Java, it would be System.out.println(thingToPrint). In Ruby, it would be `puts(thingToPrint)`. – Anderson Green Mar 18 '13 at 02:53
  • 1
    What isbadawi said. While your api may be syntactically valid, the use of it may not be idiomatic for one or more of the languages you are targeting. I personally would rather use an API that takes advantage of the language features available so I don't have to write more code. – mortalapeman Mar 18 '13 at 02:53
  • @mortalapeman Each "polyglot" function would only depend on a small number of "language-specific" functions. As soon as I had written a few "language-specific" functions for a particular language, I would be able to port a large number of "polyglot" functions to that language with only a few minor semantic changes. – Anderson Green Mar 18 '13 at 03:00
  • @AndersonGreen I think your plan is going to be more work than you think. You're talking about writing your own language as an abstraction in top of another language. You'll have to implement operators as well as the key words and all the semantics associated with them. It would probably be easier to do what ipaul said. – mortalapeman Mar 18 '13 at 03:18
  • 2
    Yeah don't do this. As everyone is saying, this is going to be way more work than you think, and it's not really going to benefit you as much as you hope. – Nate W. Mar 18 '13 at 03:35
  • @mortalapeman It wouldn't be necessary to implement a completely new programming language. Instead, I could simply use a restricted subset of an existing programming language (such as Java) instead of creating a completely new language. To keep things simple, I'd also need to use a single data type as the input and output of every function. So `String[] theStr = ["Hi!"]` in Java would become `var theStr = ["Hi!"]` in JavaScript. – Anderson Green Mar 18 '13 at 04:32
  • 1
    IMO it's more important to follow platform conventions than having an identical API. Having a similar API is probably a good idea, an identical API probably not. – CodesInChaos Mar 18 '13 at 15:02
  • Read up on FFI and interoperation techniques if you want your library usable by multiple languages. I wrote an answer to someone regarding FFI [here](http://programmers.stackexchange.com/questions/177381/how-can-i-combine-c-fortran-with-javascript/177396#177396) read further on wikipedia and google. – Jimmy Hoffa Mar 18 '13 at 15:02

2 Answers2

4

First question - is it useful? Not particularly. Trying to make one API that fits a multitude of languages is often a mistaken approach. There are several different programming types listed in the example:

  • C - classic procedural programming
  • JavaScript - multi-paradigm tending to functional and object oriented
  • Java - Object Oriented.
  • Python - multi-paradigm tending to object oriented

The way of thinking in each of these languages is particular to that language. One can try to write procedural code in all the languages - completely ignoring polymorphism and just reverting everything to C like struts, but it would not integrate well with others. It would also forgo all the advantages of writing in a higher level language. Passing around dumb objects to static procedures defined somewhere - that is so 1980s.

The question of why really shows up. What practical use would this serve? If I am writing C code, I'm writing C code. Polyglot shops exist, but they are not the norm (it is much easier to hire 6 programmers for one language and get stuff done than it is to hire 1 programmer in each of 6 languages and get the same amount of stuff done). Rarely does one find a programmer that is writing Java and C at the same time where the perceived advantage of having one library API that fits both Java and C could be of a very small advantage.

What you are talking about is implementing a domain specific language (the printSomething(String) of the polyglot API) as a runtime environment in a multiple languages. This isn't impossible, but isn't that useful either. This is harder than one imagines - Python's scope is based on indentation, Javascript's semicolon is a statement separator as opposed to the statement terminator in Java and C (and non-existent in python).

This isn't an impossible task, but really, it isn't that useful.

KaeruCT
  • 101
  • 6
  • If that's the case, then would I be better off manually porting an entire API (possibly with 200 different functions) into 8 different languages, instead of writing a single API that is syntactically valid in all of these languages (which would depend on just 10 or 20 language-specific functions in each language)? – Anderson Green Mar 18 '13 at 14:17
  • Yes. Consider the difficulty alone of writing something to make it so that there is some structure for arrays that is common to Javascript and Java - `String[] theStr = {"Hi!"}` and `var theStr = ["Hi!"]` When you can find a way to do this with the same syntax. –  Mar 18 '13 at 14:35
  • To solve this problem, I'd probably need to represent arrays as JSON strings, and then write conversion functions to convert the strings to string arrays in each language. Fortunately, there are already some libraries for this purpose: https://www.google.com/#hl=en&sclient=psy-ab&q=(python%7Cjava%7Cjavascript%7CC%23)+get+array+from+json&oq=(python%7Cjava%7Cjavascript%7CC%23)+get+array+from+json&gs_l=hp.3...27970.43223.1.43744.25.22.3.0.0.2.115.1409.20j2.22.0.les%3B..0.0...1c.1.6.psy-ab.xFYy1DV7pjA&pbx=1&bav=on.2,or.r_cp.r_qf.&bvm=bv.43828540,d.dmg&fp=c88c58e01e24d8b1&biw=1366&bih=639 – Anderson Green Mar 18 '13 at 14:55
0

The Katahdin programming language was designed to solve this problem. Its documentation includes this example, which combines Fortran and Python functions in one file:

import "fortran.kat";
import "python.kat";

fortran {
    SUBROUTINE RANDOM(SEED, RANDX)
        INTEGER SEED
        REAL RANDX
        SEED = 2045*SEED + 1
        SEED = SEED - (SEED/1048576)*1048576
        RANDX = REAL(SEED + 1)/1048577.0
        RETURN
    END
}

python {
    seed = 128
    randx = 0
    for n in range(5):
        RANDOM(seed, randx)
        print randx
}
Anderson Green
  • 563
  • 6
  • 13