views:

301

answers:

5

In the introduction to Bruce Eckel's Thinking In Java, he says, in 1998:

Programming is about managing complexity: the complexity of the problem you want to solve, laid upon the complexity of the machine in which it is solved. Because of this complexity, most of our programming projects fail. And yet, of all the programming languages of which I am aware, none of them have gone all-out and decided that their main design goal would be to conquer the complexity of developing and maintaining programs.

In the second and later editions he adds this footnote (circa 2003):

I take this back on the 2nd edition: I believe that the Python language comes closest to doing exactly that. See www.Python.org.

I am a dabbler with java, with a background in Delphi (Pascal), C, C++, and Python. Here is what I want to know:

  1. What exactly did Eckel consider when he called Python 'better' at conquering complexity, and are his thoughts on track with others who have used both?

  2. What do you think about conquering complexity? Is the shorter and more terse syntax of Python a key way to conquer complexity (and thus, for instance, Jython might be a nice bridge of Java's great libraries, and Python's terse syntax), or is the strong-typing-mentality of Java, which inherits this idea from C++, which inherited that idea from simula, I think it was, a key to conquering complexity? Or is it the Rapid Application Designer (think Delphi, or for Java, the excellent free NetBeans window/form designer tools) or components, or beans, or J2EE? What conquers all, for you?

This is already tagged subjective. [edit]

Note: More on Bruce's thoughts, on why he loves Python are found here. A key quote from the article:

Bruce Eckel: They say you can hold seven plus or minus two pieces of information in your mind. I can't remember how to open files in Java. I've written chapters on it. I've done it a bunch of times, but it's too many steps. And when I actually analyze it, I realize these are just silly design decisions that they made. Even if they insisted on using the Decorator pattern in java.io, they should have had a convenience constructor for opening files simply. Because we open files all the time, but nobody can remember how. It is too much information to hold in your mind.

So, chunk theory. By the chunk theory metric, Python kills everybody else dead. I'll grant him that. But what is the metric you use? I would like to particularly invite people to stand up for Java, and oppose Bruce, if you care to.

[Please do not vote to re-open, this subject is inherently incendiary, and my gaffes have made it more-so. I agree with the moderators.]

+2  A: 

For me, switching from Java to Python was a big win. I can write code faster, with the same or fewer bugs, and modify it more easily. The code also remains much more readable, so when I come back to it after a couple months I can figure out what it's doing faster (and rewrite it without too much trouble when I can't).

Java, being strongly typed, requires a lot of work up front to design and maintain correct type definitions. If you declare a variable as an int, and then decide it should have been a float, you'll need to change that type throughout your program. Are you storing that value in an array? You'll need to change that type declaration, too. Decide to refactor several classes to share a common interface? You'll have to change function definitions throughout your codebase to handle it. If you have a particularly complicated design, you'll find yourself having to deal with a lot of those issues.

Python also has a lot of support in the language for changing how certain things work. Python decorators, for example, can abstract away a lot of complicated code (dealing with caching, or registering functions) keeping code maintenance down. Sophisticated IDEs can help maintain your code, but you're better off starting with a less complicated language.

Chris B.
I am very interested to know that you feel your productivity went up. I guess that's the individual answer for many people. Complexity is the inverse of productivity.
Warren P
I find python less readable, by the way, in large systems. This adds complexity, which takes away from the time I saved not having to write type declarations. A class has a method "def foo(a,b,c):" Great. It takes three parameters. What on earth are they? I sure hope this guy wrote a docstring, or I'm just going to have to read 1000 lines of code to find out what a, b, and c are.
Warren P
The same goes for Java. How does knowing a is a String, b is an int, and c is a float help you any?
Chris B.
@Chris Not as much, if they're primitives. But if a,b, and c are, say, a java.sql.Connection, a Cursor, and a String, then it helps a lot. In fact, many IDEs will automagically fill in function parameters with the most recently declared item of the needed type within scope. That doesn't always work, but it does enough of the time to be helpful.
gilesc
There you go. IDE code completion plus strong typing creates a hint system. ANd if the parameter is named MillisecondTimeout, it's a moot point whether you declare "int" (java) or no type (python) because the name makes it clear. So we're talking about a pretty fine distinction.
Warren P
I think if you have an idiot who declared a function with params `a,b,c` then your problems are much worse than figuring out what the parameters are actually supposed to be. Of course there's also the fact than you can *read* the function and figure it out if it's that important and he hasn't written a docstring (which is likely a lie given this guys naming conventions)
Wayne Werner
+4  A: 

And yet, of all the programming languages of which I am aware, none of them have gone all-out and decided that their main design goal would be to conquer the complexity of developing and maintaining programs.

Almost every single language is based on conquering complexity. There is no other aim worth pursuing. Assembly, C++, Java, Python, and virtually every other language in existence is based on making programming easier.

How is python good at conquering complexity?

Python definitely has some of the most intuitive syntax of any language IMHO. Its use of block indenting solves a lot of problems, and most of it is as close to plain language as you should get. M = [x for x in S if x % 2 == 0] is a good example, see any python book for countless more.

Is the shorter and more terse syntax of Python a key way to conquer complexity?

I believe the simple syntax of python is a good way of conquering complexity. However, that's the only definitive answer I can give to your other query:

What do you think about conquering complexity?

You are asking the question that is the entire core of language theory, which encompasses battles that will probably rage until the end of time. static vs dynamic typing is one such debate. There are mounds of other developments in language theory like Procedural vs OO vs Functional languages and Aspect Oriented Programming that try to simplify programming. Look at the latest (or any) release of a language to see some examples of what's being done to 'conquer complexity'. There is never going be one definitive answer, and a full discussion of each approach would take a few months to read, and would probably completely change by the time your were done. :D

CrazyJugglerDrummer
Excellent points, both.
Warren P
Does Java do a better job in any way, of conquering complexity? The static typed languages, and the strong typing advocacy crowd (which includes me, by the way), really do see benefits from strong typing, which are (contrary to the dynamic language people's claims) a key part of how they manage (and conquer) complexity. However, I find I am unable to succinctly state why a java-style of static typing (or interfaces, if you like Springs) is key in the battle of conquering complexity, perhaps for very large code systems, where Java is most popular.
Warren P
Python becomes rubbish with sprawling and complex projects. The lack of strong typedness means that incorrect data gets stored and passed through until it finally causes an exception, the source of the problematic data unknown. Case in point: waf.
Chris Dennett
Python _has_ strong types. You're thinking of _static_ typing, which is a different issue. And I have never had a problem passing the wrong type around in a Python program that I didn't find and fix almost immediately after I made the mistake. Static typing only prevents a very small subset of problems, and not the difficult ones, either.
Chris B.
@Chris Dennett: If you let incorrectly typed data flow so deeply into your system that you can't tell the source of the data, that's a problem with your development methodology, not the language. Dynamic Typing doesn't have to mean *weak* typing - just because the language gave you a rope doesn't mean you should hang yourself with it.
Nick Bastin
Although Chris has stated his point strongly, I believe he has answered my original question. What do developers believe will help them conquer complexity? As a long term user of statically typed languages, I rely on static typing, in particular OOP principles, and class/interface design, heavily. I believe python developers who care about preventing code-rot do exactly the same kinds of validation, but they use unit testing instead of a compiler's type system to accomplish the same goal.
Warren P
Sorry about mixing up strong types with static types. Anyway, waf is a build system created in Python which exhibits many problems relating to type-safety when you make a mistake somewhere. Even deleting a 'cache' directory can cause problems, with a completely misleading exception. I'm not having a go at the project, but they need to sort these problems out.
Chris Dennett
+4  A: 

Bruce Eckel: They say you can hold seven plus or minus two pieces of information in your mind. I can't remember how to open files in Java.

I can:

new FileInputStream(filename);

I've written chapters on it. I've done it a bunch of times, but it's too many steps. And when I actually analyze it, I realize these are just silly design decisions that they made. Even if they insisted on using the Decorator pattern in java.io, they should have had a convenience constructor for opening files simply.

This is solved in a matter of minutes by writing that utility method with a simple api. And it has been. If that is the strongest criticism than can be directed at Java, I remain distinctly unimpressed.

meriton
Thank you for showing up. I was hoping someone would dare speak for Java. So what, on the contrary, makes a java developer productive, for it has not, you will agree, the most terse syntax of all?
Warren P
Not knowing python, I can not meaningfully compare the two.
meriton
That code, of course, fails if you're opening a text file, in which case you need to use FileReader. Unless you need a different encoding, in which case you'll need a FileInputStream wrapped with an InputStreamReader. And of course, 99% of the time you probably really want a BufferedReader or a BufferedInputStream. Sure, you can write a utility method to make it easier, but that's the point, isn't it? Why is it this complicated to begin with?
Chris B.
You don't have to write that utility method because somebody else already did it for you: http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html#readLines%28java.io.File,%20java.lang.String%29
meriton
So java plus apache commons libraries (which by all accounts are excellent!) makes for shorter, more readable, easier to write code. Language and standard libraries are of course related, but to a pure language theorist, a standard library is a convenience, and not an immutable thing like language. I guess if someone could write helpers for Java, it will still not be quite as concise because of the typing. As a fan of strong typing (Pascal, C, C++, Java), I feel it helps combat complexity. I am hoping some Java fan pops up to talk about that.
Warren P
Thanks for the readLines link. That really does put (I think) a hole in Bruce's particular argument. Maybe he would have to change that to some other thing which takes 50 lines of java, and for which there is no simple one liner in Java. However, I think when real-world large applications are included in the fray, and not just demo-code, Java has some huge advantages (GUI, Swing, etc, versus the messy field of too-many-90%-solutions that is Python GUIs).
Warren P
I believe the static typing in Java is the mortar that allows to build cathedrals instead of bazaar tents. (Note that it usually takes a LOT longer to build a cathedral)
Thorbjørn Ravn Andersen
We're talking about programming languages. Of _course_ you can write a utility method to make tasks easier. The difference between Java and Python is, with Java, you _have_ to.
Chris B.
meriton; without knowing python, what is the key to managing complexity for you, a java developer, and how does java address the accidental complexity ('pain', if you like) of being a programmer - does java make your life easier?
Warren P
Guy Steele (big java guy), in his famous talk Growing a language, addressed this exact topic. I believe that the creators of Java understood exactly what Eckel was talking about, and they believe that Java addresses the needs of a large number of developers. I'm curious how a Java-grokking-professional would frame a response to Eckel.
Warren P
+4  A: 

I think Bruce was taking his cue from Fred Brooks, who talks about complexity in his essay "No Silver Bullet", and describes two types. The first type is inherent in the problem you are trying to solve, which he calls essential complexity and is the same regardless of what language you use. The second is the complexity added by the tools and languages we use - all the stuff you have to think about that does not directly add to solving the problem. By this measure Java has a LOT more complexity than Python. The simplest example is the canonical Hello World program. In Python (and several other languages) it is one line:

print "hello World!"

In Java it is

class HelloWorld {
  static public void main( String args[] ) {
    System.out.println( "Hello World!" );
  }
}

most of which has nothing to do with the task of printing "Hello World" and is basically noise.

There are several factors that IMHO add to the complexity of Java compared to other languages like Python.

1) everything must be in a class. This forces you to use the OO paradigm even when it is not appropriate, like the example above, and add lots of unnecessary boilplate class definitions.

2) Even though it forces you to use classes it is not fully object oriented. By this I mean that not everything is an object, such as primitive types and methods. In python you can subclass all the builtin types and pass functions & methods around like any other object.

3) Java is not functional - in fact it goes out of its way to stop you using a functional paradigm. Being able to pass functions around and create closures and lambdas can simplify a lot of code. The closest you can get in Java is to use anonymous inner classes for things like callbacks.

3) Java forces you to put in type declarations everywhere, which adds a lot of clutter without adding useful information. This is not just a static vs dynamic issue - there are statically typed languages like Scala that can infer the types 90% of the time and cut out all the noise.

4) Although Java forces you to use static typing, many (perhaps most) real world Java programs use dynamic type checking part of the time. Every time you do a cast from an Object to a specific type you are doing dynamic type checking - before generics were added in Java 5 this meant every time you used a container class for example. Even when using generic containers some of their type checking is done at runtime. Also every time you have an XML file with class or method names in it them somewhere in the code it has to do a dynamic type check to make sure it matches up with a real class. So many Java programs still have the alleged "dangers" of dynamic typing but with all the verbosity that Java's static typing forces you to add.

I could go on (and often do), but I will stop here with the observation that I have seen a lot of code that is simpler, cleaner and less complex in Python than in Java but none the other way around. If anyone can point me to some then I would love to see it.

Dave Kirby
You can pass methods around in Java. You don't normally do so because they're *not* bound to particular objects and so don't have any interesting state associated with them.
Donal Fellows
@Donal: I presume that you mean reflection Method objects. I guess you could do some form of functional programming by passing around Method objects that refer to static methods, but this would be so unwieldy and slow that no-one does it. You also would still not get anything like closures, partial functions or lambdas.
Dave Kirby
Next year, in Java 7. :-)
Warren P
@Dave: Yes. As noted, they have no “interesting” state associated with them.
Donal Fellows
@Warren: **;-)**
Donal Fellows
+1  A: 

Having earned an A in my "OOP With Java" course last semester, and self taught in Python for a few years now, plus being interested in programming in general, and having written several K lines in both languages (not counting the comments), including a Jack lexer/parser in Python (and seeing the equivalent performed -- or not -- in Java by my compatriots), I think I have enough experience to be worth at least a few cents anyway. Or not, but now that I'm done tooting my own horn you can decide for yourself ;)

First of all, I agree wholeheartedly that programming is about reducing complexity. I also agree that Java does not do a great job at reducing complexity.

For instance, to get user input from the command line?

Scanner input = new Scanner(new BufferedReader(System.in)); (I think? And it's only been 2 or 3 months since I've used that)

Python is raw_input() and in 3.0 it's just plain input()

How do you read from a file in Java? Well, honestly I don't know. We didn't do much of it, and it was worse than Scanner. As has been mentioned, the complexity of Java is above and beyond that of any other real language I know, but not quite so bad as "that" language.

I think the main problem with the complexity of Java is found in the example meriton uses in defense of Java. Rather than importing awesome community APIs and implementing them as part of the language, Java has a "core" language and APIs are just an extension of that. What I find interesting is the wealth of tools that Java has to build APIs and documentation for said APIs. I mean, you write your code, put in some certain comments, and (at least in Eclipse) select an item inside a menu and you have generated some beautiful javadocs. Even though it's wonderful to have such great documentation, I wonder if it didn't actually evolve out of necessity because looking at a program gives you no clue what Java is doing. Scanner? Buffered Reader? WTF?? There are layers and layers of added complexity that could (and some argue should) be abstracted away. Heck, I can open and read a file in assembly with less fuss than Java. Of course comparing a few lines is really rather trivial and fairly worthless, but the point is that Java often introduces complexity, rather than solves it.

Here is the biggest reason that I feel Python has the advantage: useful types/functionality is built-in to the language, and they tend to be very well named (and at least if they're not super well named, they at least have some hint).

For instance, let's say I want to open a comma separated file (without using extra APIs or imports), and store each element in a generic collection.

In Python (2.6+, or 2.5 with a import from future) it's literally two lines:

with open('myfile.csv') as f:
    print f.read().split(',')

done.

In Java I don't think you can do it without importing external classes. Of course in reality I think either language just goes to preference, and possibly either genetics or training.

Some people feel that static or dynamic types introduce the least complexity. I fall into the latter camp, but I understand the argument. After all, your compiler will complain if you try to pass a different type, and you always know what something is supposed to be, because it's either explicitly declared or cast as such. Of course that adds the complexity of the casting operation (minor as it may be), but it benefits from not having to wonder "How in the world did the integer I passed in turn into a float|string??"

But when it comes down to it, most people can take a look at a Python program and understand what's going on. Novice programmers to extremely advanced programmers will be able to comprehend the program and purpose by looking at it. Heck, I just wrote a plugin for Bazaar by a combination of reading the (poor) documentation and reading the code for the Bazaar built-in functions. It took relatively little effort, and they even have a few custom definitions. The same thing for some golly scripts. When coding stuff in my Java class, I was also able to understand some other classes. However, I think I was at a severe advantage in that class because the Java concepts are very similar to Python concepts. Or vice versa, whichever way you prefer. (Or they're both similar to Lisp concepts ;)

I guess honestly I think the complexity is just the learning curve. Python has a very shallow learning curve, with the power being an inverse function to the learning curve. Java has a steeper learning curve, with its power curve having a linear (2x? 3x?) relationship. Once you've learned the language and the underlying concepts, the complexity is reduced to near-zero for both languages, I think.

Wayne Werner
Interesting. So far, I have found zero people who have tried both, and prefer Java enough to say so in great detail. Personally, I have tried both, and remain unclear in my preference. Netbeans+Java has superior GUI tools, to anything I've ever seen in Python. However, for writing non-GUI apps, I can be many times more productive in Python. oddly,that productivity goes negative on me when I try to use Python to do windows GUI work. wxPython and pyQt and tcltk don't do it for me.
Warren P
I've never used Netbeans Gui tools, and I've tried Glade for Python. If I were more familiar with the tools I would probably be more productive, but honestly right now (on the occasions I do GUI with Python), I feel a lot faster coding Guis via straight code. Having used straight code in Java I can also tout Python FTW - you can use grid or you can pack (at least in pyGTK). You don't need 4+ layout managers that all require convoluted settings to get a good layout. If I'm just trying to hack together something simple in python, Tkinter is my choice, though rusty so I use the docs a lot.
Wayne Werner