Programmer Tips‎ > ‎

Best Programming Language?

posted Jan 13, 2012, 7:47 PM by Tyler Akins   [ updated Jun 8, 2012, 10:25 AM ]
Occasionally, people will foolishly ask me for what I believe is the best programming language available. My answer is usually, "What are you trying to do?"  My belief is that some languages are better than others for particular tasks.  For instance, one would want to write graphics drivers in C, C++ or assembly for speed.  Likewise, we write applications on the web using a mix of JavaScript and some sort of scripting language backend such as Ruby or PHP.  To get at the core of the issue, first we must understand our restrictions and our goal.  After we truly understand where we want to go, often a particular language will win over the others.

Often times it will be a language that is interpreted because they will handle more of the nitty-gritty things for the programmer.  This is a huge benefit since programmers will only pump out X many lines of code per day.  You'll want those lines of code to be in as high of a language as possible; in assembler you can probably write an itty bitty function in 7 lines of code, but in node.js you can write an HTTP proxy.  Higher level languages will let programmers be far more productive.

Hackers and Painters

In Hackers and Painters by Paul Graham, there is much talk about Lisp and how this mathematical language is still very powerful.  Graham attributes this to nine aspects that Lisp has that were new to languages of that era.

1 - Conditionals

This would be your standard if / else block.  At the time, there were machine-specific comparisons and then you would use a goto.  Today, a language that doesn't support "if" statements is not considered a real language.

2 - A function type

In Lisp, a variable can hold a number, string, or a function.  Functions can even be passed as arguments. Some languages today implement this, but certainly not all.

3 - Recursion

Lisp functions can call themselves.  Other languages perhaps looped, had to manually handle the stack for arguments, or needed to employ tricky tactics to get the job done in a similar method.

4 - Dynamic typing

A variable can hold a string, number, function, or other forms of data.  One does not need to declare the datatype ahead of time.  With Lisp, variables are essentially pointers to data and the data is what has a type.  Assigning a value to a variable merely copies the pointer.

5 - Garbage collection

When you were done using up memory, you would normally have to free it.  With Lisp, the variables would be deallocated eventually and automatically.

6 - Programs composed of expressions

Lisp doesn't distinguish between expressions and statements.  An expression calculates a result (like "4 + 5") and can be viewed like a phrase.  A statement also does something with the result (like "x = 4 + 5") and can be understood like a whole sentence.  In Lisp, when an expression is evaluated it always produces a result, which can be fed into another expression to build another result.

7 - A symbol type

References to a symbol are really pointers to strings in a hash table.  Ruby has this concept, and it makes comparisons much faster.  If you have a certain string in your code multiple times because you are comparing it here and there and everywhere, symbols would have one copy of the string in memory and every time you used it there would just be a pointer to that one string.  On the other hand, in C you would end up with multiple copies of your string.

8 - A notation for code using trees of symbols and constants

When in memory, programs are written as lists of symbols and constants.  These lists may also contain lists, and those might contain lists, etc.  Thus, all of Lisp is stored in trees internally.

9 - The whole language there all the time

This one is aimed at the parser, compiler and runtime being always available.  While reading code it could execute code to reprogram Lisp's syntax.  While executing code it could compile more code to extend Language.  One could run code to parse more data, perhaps as a form of communication with another piece of software.

One problem with the book Hackers and Painters is that they do not go into why this sort of thing would be powerful and why it gives Lisp such an advantage over other languages.  It discusses partly that since programs are just lists and functions can be treated the same as any other variable, one can mutate functions and alter how they run without much fuss.  That sort of flexibility might give huge amounts of power, but unfortunately I have not yet been witness to where that's a good idea and other languages didn't have a solution that would work for them as well.

Today's Languages

Lisp has the above things and was designed in the 1950's, and it appears that other languages have been trying to achieve many of the above items after learning that they do work well.  Here, I shall attempt to compare other languages with some of the above criterion that set Lisp apart from other languages.  I'm going to exclude some that are in every modern language and also remove the "notation for code using trees" since that's how one language works internally, which may or may not actually empower the programmer.

Attributes

  1. [Fn] Functions can be assigned to variables
  2. [Dyn] Dynamic typing
  3. [Gc] Garbage collection
  4. [Sym] Symbol type (natively)
  5. [All] Whole language there (eg. can use "eval")
  6. [R] REPL: Read, eval, print loops

Language comparison

Language [Fn] [Dyn] [Gc] [Sym] [All] [R]
C No No No No No No
Java No No Yes No No No
JavaScript Yes Yes Yes No Yes Yes
Lisp Yes Yes Yes Yes Yes Yes
PHP Partial Yes Yes No Yes Partial
Ruby Yes Yes Yes Yes Yes Yes
Visual Basic No Yes Yes No Yes No

PHP can pass closures as functions but doesn't treat all functions this way.  The command-line interface does have an interactive mode, but it won't load library functions by default.
Comments