The following are required for maximum programmer productivity: (please try to keep this from degenerating into yet another LanguagePissingMatch)
The main ones:
AutomaticMemoryManagement?: Some languages had this earlier than others. Languages which started out without it sometimes evolve idioms for it. see LateCeePlusPlus.
High Level Error Reporting: If a program has an error like indexing an array out of bounds, the error should be reflective of that and not some sort of machine fault, stack corruption, memory overrwrite etc.
Fast Compilation. It's not productive to wait 5 minutes for a big program to link.
Not quite as important:
Sugared collection syntax: It should be easy+ to do something like the following:
for [x,y] in [ ("cat",2), ("doc", 4}, ("man", 45), ("bear", 32)] print ycheck this history for a mention of using templates in C++ and why the easy+ disclaimer was added.
Isn't sugared collection syntax just a special instance of what I woulc call Expressiveness?
PatternMatching: This saves a lot of time. Lisp and Csharp etc. fail here. It takes too long to do the equivalent of:
[x,rest]=some-list 'x takes on the first element of a list.
(defmacro dst-psetq (target source) (labels ((getsyms (tree) (cond ((null tree) nil) ((and (symbolp tree) (not (eql (elt (string tree) 0) #\&))) (list tree)) ((consp tree) (nconc (getsyms (car tree)) (getsyms (cdr tree)))) (t '())))) (let* ((symbols (getsyms target)) (newsyms (mapcar #'(lambda (sym) (gensym (string sym))) symbols)) (mapping (pairlis symbols newsyms)) (newtarg (sublis mapping target))) `(destructuring-bind ,newtarg ,source (psetq ,@(mapcan #'(lambda (pair) (list (car pair) (cdr pair))) mapping))))))No wasteful tokens:
Lisp is pretty gross this way. What Lisp gives in productivity, it takes back in matching syntax. C#, C++, Java, etc. require all sorts of extra tokens to make them easy to parse. Developers frequently waste time because their eye is fooled into thinking something is at one scope since people perceive indentions naturally, but a mistake has been made about the indentation.
XSLT is pretty bad in this regard too. What it gives in the power of xpath and pattern-matching, it takes away in tagged text.
But note that one person's wasteful tokens actually help readability to many other people... there's no one perfect language.
Debuggable: You need to be able to put a debugger on code and figure out what's going on.
Easy Refactoring: You need to be able to change or add and test a small peice of code without having to futz with a bunch of other methods or classes. In contrast, if you implement an interface in JavaLanguage or CSharpLanguage, you need to stub out all the methods of the interface, write the one you are interested in, remember the class is unfinished with stubs that just compile. Dynamic typing and RefactoringEditors? for statically typed languages might be solutions.
There is some uninformed critique of Lisp/Scheme here.
PatternMatching: This saves a lot of time. Lisp and Csharp etc. fail here.
It is very easy to provide pattern matching macros in Lisp/Scheme. Actually, most Scheme implementations come with pattern matching macros. See, for example, the book OnLisp, or the pattern matching macros (the match.ss module) provided by MzLib?, which is one library that comes with MzScheme. You can find the documentation here (http://download.plt-scheme.org/doc/). (Sorry, I couldn't provide a more direct link as the links to MzLib? documentation are fragile (version number and chapter number.)
What Lisp gives in productivity, it takes back in matching syntax.
Just don't waste time matching parentheses visually without tools! A good editor/IDE will highlight parenthesized expressions when you move the cursor to the beginning or the end of such an expression. A good editor will also perform indentation automatically and allows you to move the cursor by the structure of the expressions. I find that it is much faster to edit Lisp/Scheme code than it is to edit less structured languages, because it is so easy to select an entire expression (not just the first token of the expression). Of course, editing speed is hardly the highest-order term in programming.
I'd like to add polymorphism to the list of requirements. I recently added SSL support to a web server written in C. Unfortunately, SSL sockets can't be used with the recv and send functions you use for regular sockets; you'll have to use SSL_read and SSL_write instead. This sort of thing can be a real pain.
+ Easy is defined as: either directly via the langage or the language allows one to extend itself via standard actions