perjantaina, tammikuuta 02, 2009

The best programming language

I have been doing most (well, pretty much all) of my professional programming in the C language. I'm beginning to really hate it. It is so difficult and error-prone to do string manipulation in C. It is easy to leak memory. There are no standard high-level data structures.

I have been looking for alternatives for a long time. The alternative should:
  • have good libraries
  • have good interface to libraries written in C
  • have support for threads
  • be small
  • have good performance
  • not have many dependencies to operating system libraries
  • it should be possible to make closed-source programs with it
I have looked at Smalltalk, Erlang and Python.

Smalltalk has good libraries and the Smalltalk virtual machines tend to have very few outside dependencies. The Smalltalk I'm best familiar with, Squeak, has no support for threads and seems to interface somewhat badly to the outside world. I was especially disappointed by its support for running subprocesses and controlling them. Also, it is pretty much impossible to make closed-source software with Squeak. All the source is included in the image or can be reverse-engineered easily.

Erlang is an even more niche language than Smalltalk. There aren't many other people using it. Erlang is difficult to extend with libraries in C. Apparently not many C libraries can easily live with the extreme parallelism and thousands of light-weight processes a typical Erlang environment looks like. OTOH Erlang has good support for running subprocesses and communicating with them. Erlang sucks particularly bad in performance, unless your problem parallelizes to the extreme and you have the hardware to support it. For the more conventional cases Erlang is probably not a performance booster.

Python is sexy but slow. Python is also mostly single-threaded. It has threads but only one of them can execute in the interpreter at once.

Java is very un-sexy and also very slow. It has good thread support but it is a huge bloated monster.

All the languages above are very big. I call it very big if the customer has to install 30+ MB of language support/runtime/virtual machine to deploy a piece of software.

At the moment it looks to me like C++ or Objective-C would be the solution. Also there is this thing called Haskell, but I haven't looked into it sufficiently to have any idea how it stacks up with the contenders above.

8 kommenttia:

DSmith kirjoitti...

I would avoid C++ like the plague. Perhaps sequentially faster than most of your other picks, however this is a diminishing factor for most applications these days.

Highly concurrent server are ideal for Erlang, especially if you require a long-running fault-tolerant systems. If you plan never to take your system down, Erlang is what you want to use.

Python and Ruby have great libraries and active communities. Great for small, discrete tasks.

Smalltalk and Objective-C are in decline.

Haskell looks very cool, but will it ever make it out of the labs? It will be sequentially faster than Erlang in most cases because it's statically typed; it has lazy evaluation which can eliminate unnecessary computations; It has an interesting concurrency model ( I think based on monads ). I definitely plan on giving it a go this year.

Timo kirjoitti...

"Python is slow". Is it a myth or have you personally made some piece of python code that you have then had to convert to (Obj-)C(++) because of performance problems?

To try to prove my point, I made a simple program that would sort lines it reads from stdin in both C++ and Python.

Python:

#!/usr/bin/python


import sys
lines = sys.stdin.readlines()
lines.sort()
for l in lines:
sys.stdout.write(l)



C++:

#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <algorithm>


int main(int argc, char *argv[])
{
std::string s;
std::vector<std::string> a;

while (getline(std::cin, s)) {
a.push_back(s);
}

std::sort(a.begin(), a.end());

for (std::vector<std::string>::iterator it = a.begin(); it != a.end(); ++it) {
printf("%s\n", (*it).c_str());
}
}


My plan was to time(1) them and then add the compilation time of C++ program to its execution time.

But what do you know. On my MacBook Pro with OS X 10.5.6, running the c++ version for 46113 input lines takes about 310 ms. The python code achieves the same in about 90 ms. (and compiling the C++ code took about 350 ms)

I'd say myth busted. (plus the python code is only 9 lines, whereas the c++ extends to 23)

Of course the thread support in Python is what it is, but weren't threads passé anyway..? I haven't checked, but isn't Ruby supposed to have actually working thread support, should you need threads in your scripts.

sti kirjoitti...

Timo,

"Python is slow" is, I guess, somewhat a myth. I know Python is slow in calculations and pretty fast in I/O.

I haven't used Python in anything really demanding, except in one program that tried to parse MPEG2 program stream. In that application I found Python to be slow. I was told method calls are very slow in Python, so I tweaked the code accordingly and got an improvement of a couple of magnitudes.

It would be nice to have the luxury of breaking your code to small functions without worrying about it becoming slow.

OTOH, like I said, my experience in Python is limited, so I have to take your word for it...

sti kirjoitti...

DSmith,

I have been taking a closer look at Erlang for a few days now and I'm making a small prototype to see if it meets my requirements. I'm liking what I'm seeing so far, except for the "myth" of slowness of file I/O (I will find it out myself) and the size of the VM (>100 MB), although I haven't looked into if it is possible to trim it if one doesn't need all of it.

sti kirjoitti...

DSmith, do you have any pointers to a mailing list of discussion forum where Erlang newbies can ask questions?

Unknown kirjoitti...

Java isn't slow any more. The JVM (Java Virtual Machine) has been improved a lot, and is on it's way to passing C++ in speed.
With a JIT (Just-in-time) Compiler like the JVM has, you have runtime information to optimize code. So the JVM has information that it can use to optimize code at runtime that a C++ compiler could never have at compile time.
Another language to look at is Clojure: http://clojure.org/
It runs on the JVM, and is desiged for concurrent programming. Also, it's a lisp, with all of the advantages of code-as-data.
If you really don't like lisp, you could also try Scala: http://www.scala-lang.org/
Scala also runs on the JVM, and has an actor library that mirrors Erlang's actor model.
But both of these languages have the benefit of Java interoperability. They can call Java code, and can be called from Java.

Anonyymi kirjoitti...

I recommends following sites:

For flaws in benchmarks:
http://shootout.alioth.debian.org/gp4/miscfile.php?file=benchmarking&title=Flawed%20Benchmarks

The Computer Language Benchmarks Game:
http://shootout.alioth.debian.org/

And finalyl my absolute favourite,
"The speed, size and dependability of programming languages":
http://gmarceau.qc.ca/blog/2009/05/speed-size-and-dependability-of.html

I like C, but i'd also like to know how to do this all in assembly...

Anonyymi kirjoitti...
Blogin hallinnoija on poistanut tämän kommentin.