public class Test
{
public static void main(String[] args)
{
for (String s : args[0].split("\\s+"))
System.out.println(s);
System.exit(0);
}
}
Snore. Guess where I stopped reading. Right where he stuck a completely pointless System.exit(0) for no reason except to boost linecount (linecount being the evilest evil known to man)
Lines of code accrue the same way interest does. An extra percent of yearly return may not seem like much in the first year, but after 50 years the difference is huge.
The same goes for code: 10 lines of java doesn't seem much larger than 5 lines of python, but after 2 years of hacking your java app can easly be 10x the size of a python app.
Reminds me when steve yegge was comparing languages, he complained about not being able to just type "quit" or "exit" in the python shell, unlike ruby. Focusing on the trivialities really doesn't help other then make the author feel smart like they have reviewed a langugae.
(BTW, you should try getting out of the haskell ghci shell, man, that thing just doesn't want me to quit).
Programming drains you in innumerable nickel and dime increments. Each tidbit that you "just have to know" is a tiny bit of cognitive load you have to tow. This not only applies to languages, but libraries.
A few trivialities are meaningless. Thousands of trivialities will drain you, and a few of those will slip through and become bugs.
in pythons case its consistency, not lack of polish. If you try to do "exit" now, it tells you to either call exit() function (thats new), or ctrl-D/EOF to quit. Now it can't be lack of polish as it knows what you are trying to do, its just it is catering for the larger picture which is to educate you on how the interpreter works.
def increment(key):
value = None
def do_incr(key):
value = self.counter_table.get(key)
if not value:
self.counter_table.add(key, 1)
value = 1
with_lock(self.lock, do_incr, key)
Several reasons:
1) It refers to 'self' yet isn't a method.
2) In python you can't rebind variables outside of your scope. The change to value within do_incr won't work. You can operate on objects in the enclosing scope but you can't rebind them. This used to be a source of constant annoyance to me, but I've now got into the habit of just creating small objects in place for situations where I need to do that.
Also, this java example can be improved.
buf = StringBuffer()
buf.append("I don't recognize the command \"");
buf.append(s);
buf.append("Sorry.");
message = buf.toString();
The code certainly hasn't been tested - it's missing a 'new' and the resulting string has unbalanced quotes. Regardless - don't use StringBuffer unless you need the synchronization.
Do this instead:
StringBuilder buf = new StringBuilder(); {
buf.append("I don't recognize the command ");
buf.append('"').append(s).append('". ');
buf.append("Sorry.");
}
message = buf.toString();
This tactic of creating scopes to hide away detail while you build up objects works particularly well for situations where you're instantiating streams because your file input streams and the like can be hidden away in a mini scope and this makes it far less likely to run into a situation where you can't call a second file input stream 'fis' because you used that name higher in the method.
Also, it allows readers of your code to focus on the objects that are significant to the flow of code rather than the code used for building them up.
Regarding 1: You can refer to 'self' when you have bound it - it does not have to do anything with methods. Though 'self' is usually employed in methods.
Scala currently answers every one of the author's beefs, except for reflection. Scala runs on the JVM and is a Functional/OO Hybrid language that supports static typing and type inferencing. Bottom line - full Java interop and removal of Java's high cerimonial cost without the speed penalty imposed by dynamic languages.