What makes a programming language good? I propose: ---- The quality of a language ''for a particular domain'' is determined by: * The degree to which the language reflects the domain. * How much of the functionality of the program is expressed by its source code. ("no magic") * The level to which it supports DontRepeatYourself (DRY). * ''Fits the way I think and work (rather than how you think and work)'' Note that each of these criteria represent a continuum of possibilities, not a binary yes/no choice. Also, I don't think it's possible to judge the quality of language without considering the domain it's used in. -- JimLittle (thanks to ShaneWarden and NickForrette for their help in refining these ideas) ---- ''A year later, I think I have a better starting point...'' * A good language makes it easy to create a GoodDesign. Great languages make the GoodDesign obvious. In this definition, the "good-ness" of a language depends on the program being written. --JimShore (aka JimLittle) ''(now back to the original discussion...)'' ---- Some examples: C in the domain of device drivers: * The domain is computer hardware. C reflects this domain very well. * C doesn't do anything that isn't directly specified in the program. It scores well here, too. * C has functions, but little other support for localizing knowledge. It scores poorly. C++ in the domain of business software: * C++'s syntax reflects computer hardware. It scores poorly. * C++ has several cases (such as the four default constructors) where programs' functionality is not expressed by its source code. It scores poorly here, too. * C++ has functions, objects, inheritance, and templates. It provides many opportunities for the DRY principle. It scores well. Perl in the domain of log file analysis: * Log file analysis is mostly text manipulation. Perl has many syntactic constructs that reflect this domain. It scores well. * Perl has a very large number of cases in which ''leaving source code out'' results in ''added'' functionality. (Examples: the default operator, while <>) It scores very poorly on this point. * Perl has functions and objects, but both are poorly supported. It scores neutral at best. ---- '''Discussion''' As of 2003-02-25, the discussion below is all between GarethMcCaughan (generally signed "--g") and JimLittle (generally signed "--JL"). GarethMcCaughan has done a bit of refactoring on it to avoid the disaster of InterleavedParallelThreadMode. ''What does it mean for a language to reflect a domain?'' I'm not sure that the crucial notion of a language "reflecting" a domain is any better defined than that of a language being well suited to a domain. For instance, suppose you're writing a flight simulator. ''No'' language (so far as I know) has anything much in it that's specifically tailored for writing flight simulators. ''Every'' serious language has the basic mathematical functionality you need. Does that mean that C++, Common Lisp, Fortran, COBOL and Visual Basic all score equally here? I hope not. --g Well, yes. All score equally poorly '''on this point'''. Fortran might do better because it's got more mathmetically-oriented syntax. Lisp might do a little worse because it doesn't use infix (depending on whether flight simulator people think in infix or postfix). On the other hand, Lisp allows you to create new syntax, so that could be a saving grace. Introducing new abstractions is an idea I didn't really cover that perhaps deserves more attention. --JL In that case, for a very large range of domains it's going to be true that no mainstream language "reflects" the domain to a significant degree. Hence my comments below under "Adaptability to a domain". -- GarethMcCaughan ''Adaptability to a domain'' It seems to me that a key question is: How easily can one extend the language and its libraries to "reflect" the domain? This depends on how well the language fits to begin with ''and'' how malleable it is. There will generally be some correspondence between malleability and support for the DRY principle, but these are separate issues. --g Good point. --JL ''What's magic?'' I find the "no magic" criterion a bit unilluminating, too. Suppose you have a language that "reflects" its domain very well indeed; so well that a lot of the key abstractions of the domain are available directly in the language or in its libraries. Then a lot of important functionality will not be visible in the program -- but isn't that a ''good'' thing? --g This is the point I struggled most with. Some languages have very syntactic shortcuts that lead to very complex results. So complex that it becomes nearly impossible for even experts to predict what the language will do. The interaction between templates and cast overloads in C++ is a one example. Perl is a more straightforward example. I don't know how to say what I'm thinking in a simple way. Basically, I'd like a competant programmer to be able to understand the program without needing to know all the idiomatic "gotchas" and shortcuts. Some call it ThePrincipleOfLeastSurprise, but I don't like that, because it's been used to excuse exactly the kind of behavior I dislike. One last thing on this: I wasn't trying to exclude reasonable abstractions. I'm okay with "read line from file;" abstracting the open and close operation. What I'm not okay with is a programming language that says "all programs start with an implied 'read line from file' statement unless the first statement has a 'read' keyword." Don't laugh! C++, Java, and Perl, all have constructs along those lines! --JL The trouble is that one person's magic is another person's convenience, and that with enough experience of a language nothing is very surprising any more. (With some languages, such as C++, it is possible that "enough experience" is more than one can attain in a single lifetime without insanity.) Declaring "magic" bad amounts to saying "no language features you have to get used to", which isn't a bad principle but may make it impossible to provide important conveniences to more experienced programmers. My taste, like yours, is for languages where there isn't much "magic". One of my languages of choice is Python, where "Explicit is better than implicit" is a major design principle both for the language and for programs written in it. And I, too, shudder at some of the things Perl does. On the other hand, it's not clear to me that they're all really ''bad'', rather than just ''not to my taste''. How about the following principle? "Everything a program does must be visible in its code at some level, clearly enough that an averagely experienced user of the language can reasonably be expected to know, at least, where to find an explanation of what's being done." Maybe that's too weak; it's certainly not snappy. --g ''Partitioning language applications into domains, and in other ways'' It's true that the quality of a programming language depends on the domain it's to be used in. But (1) it depends on a bunch of other things too, such as who's going to be using it, and (2) it's reasonable to ask for some measure of overall quality across a variety of domains. Ultimately, the quality of a language is only defined when you specify every detail of how it's being used, by whom, for what, in what environment, and so on. Anything more general is an approximation, and that applies just as much to "for log file analysis" as it does to "er, for, y'know, all that programming stuff". The only difference is that broader sets of language uses inevitably produce less precise measures of suitability. And one can slice the space of language uses in ways other than by "domain". For "applications where you need all the speed you can get, but also require quick and easy portability across a very wide range of systems of various sizes", it's a fair guess that C will come out comfortably on top, despite its many deficiencies. Not that that's as important a set of language uses as is commonly thought :-). And there are some issues that are completely ignored by the criteria above, which I can't believe have ''nothing'' to do with the quality of a language. For instance, whether it's feasible to implement it so that programs written in the language run quickly. --g I think looking at the domain is more interesting than the other variables. --JL Sometimes. But consider: when someone is wondering "What language shall I learn now?", what they care about its its quality for the set { things I'm going to do in the next while }, or something like that. For many people, most of those things will be in a small range of domains, but not for everyone. When someone's designing a new language, what they care about is whether there's any large and reasonably coherent set of uses that they can greatly improve; they might target novice programmers, or applications where the only thing that matters is maximum speed, or programming within a particular company. Three of the languages I like best are C++, Python and Common Lisp. I like C++ because it makes it possible to write very fast programs that are still very portable; I like Python because it's possible to write software in it quickly and have something you can return to 6 months later and still understand it; I like Common Lisp because you can do just about anything in it, even if you haven't quite worked out yet what it is that you want to do. None of these qualities is domain-specific, but for the most part the domains I work in aren't closely enough modelled by other languages to make anything much better for me than those three languages. --g ---- If I might use an allegory, while domain influences language, I would suggest that commerce, i.e., the transaction between domains, influences language more than domain. -- JonathanSmith ----