There are two kinds of programming languages :
- ExpressiveProgrammingLanguages exist to allow the programmer to express what he / she wants. To let the programmer instruct the computer as simply and succinctly as possible.
- RepressiveProgrammingLanguages exist to discipline programmers. They constrain them to organize the program in a specific way.
Compare : TypesOfProgrammer
Alternative : AlanKay says they're either the agglutination of features or theyre a crystallization of style. : http://patricklogan.blogspot.com/2005/03/alan-kay-again-on-software-engineering.html
New in 2006
Here's what I now tell my students.
Just to note what I always tell my Programming Language class. Alan Kay (inventor of SmallTalk) wrote that "higher level" is synonymous with "later binding". In other words, the more things that are bound later, the higher level the language is.
My take on it is this. The more things that are bound at run-time, rather than compile-time, the more context aware the language is. The more it is able to take note of and adapt to its environment. Look at how Ruby on Rails uses metaclass hacking to dynamically update its classes as the description of the tables in the database changes.
Earlier, static binding, of variables to types, of function calls to blocks of code, of classes to particular data-structures, means that the code you write is context independent, a one dimensional list of instructions. Later, dynamic binding, of variables to types, of message selectors to blocks of code, or classes to data-structures, means that more of your code becomes more abstract, generic, fluid, meta-recipies which say "in this context do this, but in that context do that, and in t'other context do t'other thing"
It's not simply the extra finger-typing involved in static binding that's a problem. The compiler checks and restricts the behavior of programs to a well defined and (hopefully) understood set of behaviours. But this necessarily involves preventing more meta-level, generic, context-aware programming. Programmers working with static binding have to predict the future more accurately because they can't expect the code to adapt to it when it arrives.
Java's an interesting case. A lot is made of the kinds of adaptability that are available at (or close to) runtime; of how its polymorphism allows new behaviors to be slotted into old code. But it's less noted how all this dynamism is too ordinary to mention in the context of dynamic languages.
The more you think about patterns and good practice and underlying principles in Java, the more obvious it becomes that they exist to maintain a modicum of dynamism against the dead-hand of static binding in the compiler. Favour composition over inheritance? Only because you can't change the inheritance hierarchy at run-time, but you can slot in another Strategy object. (Assuming you got your dependency injection right.) Design to interfaces? Because you don't want to be anchored to particular class names in your code.
Well, in most dynamic languages, you can change the inheritance hierarchy at run-time (and add another mixin). Arguments aren't burdened with type restrictions, so you can be sure that you'll be able to pass anything you need to to a function, however unpredictable it was to the original authors.
All those expensive pattern-language books? All that training and time spent on good design? All to overcome the static bindings between variable and type, class and superclass, which the compiler set in concrete.
Phil, isn't this just the dimension around which you care about programming languages? Indeed, you may as well have labelled the first class 'good' and the second class 'bad' ;) Going further I may suggest that one person's 'repressive' is another person's 'readable'.
Well, I'm not trying to hide my own tastes and proclivities. I talk about them all over the wiki, and I certainly hope people who read here understand that :
- a) everything here is opinion,
- b) everything here can be argued with (ArgueAgainstMe), and
- c) there might always be value in considering whether, or how it might be if, the opposite were true (CounterThinking)
I wouldn't want to pose as "the voice of authority", because such things are always bogus.
Having said that, I disagree that this distinction is merely something personal to me. I think that the two categories are fairly generally recognized and understood in the kind of discussions I follow ( on places like Artima, JoelSpolsky's site, ManageAbility or here : ) http://www.martinfowler.com/bliki/SoftwareDevelopmentAttitude.html ) Even if they're called different names, or the argument is focused on one specific theme, eg. CheckedExceptions or StrongTyping.
And I think there is a real, objective way of telling which type of language you are dealing with. When people explain features of the language, are there ever explanations that go something like "if the language didn't have this feature then programmers would ...".
I'd say if any feature is explained that way, you're dealing with a repressive language. That doesn't mean many people don't prefer to use repressive languages, and find them more useful than expressive ones. That preference, is indeed, personal. If you wanted to use less prejudicial terms, perhaps we can call them : constraining languages and unconstraining languages.
(I don't accept the readability claim, PythonLanguage is far more readable. Oh! But maybe you'll claim that's because it represses me by forcing indentation when I might choose to put everything on one line ... so be it, you might have me there. :-)
Java rant moved to JavaLanguage ;-)
How about ""if the language didn't have garbage collection then programmers would not allocate and free memory properly"? Most, if not all, language features can be rephrased to be repressive with a little effort.
Personally I think it's a continuum not a binary. Is Java repressive? Compared to Lisp? Compared to C? Compared to Z80A assembler? Context is everything. Dig a little deeper and you'll soon be talking about the advantages and disadvantages of individual features - and then we're doing language design :-)
maybe the way to get the distinction between "repressive" and merely higher-level and hiding some messy details, is whether the feature makes the programmer do more stuff. For example, while garbage collection does prevent the programmer explicitly allocating memory and doing other unsavory tricks, this is all transparent. It doesn't require the programmer to write extra code. That's different from, say, a language which requires programmers to explicitly declare variables - do extra finger-typing - which I'd count as repressive.
Personally I think it's a continuum not a binary.
Of course, this dimension is just a kind of rough "principle component analysis" attempt to squash a higher dimensional space into something we can talk about. My experience, though, is that some issues are good predictors of others. People who like strong typing because of the protection it offers are probably sympathetic to checked-exceptions too.
: That's not been true in my experience. I know lots of people who like staticly typed languages who think checked exceptions are a huge waste of time and cause many more problems than they solve. – AdrianHoward
OTOH, I suspect garbage collection doesn't predict so well. People who don't like garbage collection probably either a) just don't like the implementation they have to work with, or b) are absolute speed / efficiency freaks who want total control.
Is Java repressive?
: In comparison to what? For a C programmer Java is a breath of freedom – AdrianHoward
LispLanguage? Don't know as I haven't used it in anger. I suspect dialects differ. C, no. Though maybe more than BCPL :-)
I'm happy to accept there are other dimensions. For example, the equally hard to define high-level / low-level distinction is probably more important as an indicator of which langauge I'd prefer. But, off the top of my head, I can't think of any other dimensions more important. Always open to suggestions though.
It just sounds like a hugely subjective dimension to me. Like the pointless flame wars about whether something is "agile" or not. There is no "agile" only less/more. It's a continuum not a line. – AdrianHoward
Manageability has a larger taxonomy : http://www.manageability.org/blog/archive/20030502%23theperfectthinkingstylefor/view