Saying "Java will always be slower than C++" is like saying that there will always be less graduate students than undergraduates. Java and C++ live in the same Von Neumann-ian world, but C++ is allowed to muck with pointers, and Java isn't. Moreover Java has garbage collection.
Welcome to the world of optimizing compilers and runtimes! Both things can actually help application performance, because they allow the language implementation to do smart things.
For example, some implementations of malloc() have quite a noticable overhead, while allocating an object with a generational gc has an overhead of increasing one pointer. Additionally, you get better locality, and the order in which space is reclaimed is better suited for the real usage pattern than what human programmers tend to come up with, to the point that some objects may never be reclaimed, because it just wouldn't pay off enough.
That indeed doesn't make Lisp wrong, mainly because that isn't what Lisp does. Probably you only know Lisp from some weirdo half-of-scheme course at uni or something, but I am heavily using lots of non-lambdaish constructs in my Common Lisp code, like destructive modifications of Arrays, Objects and Methods, etc. Believe you me, people who, say, try to explain variables in terms of anonymous lambdas are just showing off, nobody uses this in practice.
The only part of Lisp where lists (and trees build of nested lists) play a vital role nowadays is manipulating Lisp programs, that indeed happen to be Lisp lists. I.e. Macros. Hard to call that a misfeature of Lisp, because about every language becomes a parse tree sometimes, it's just that Lisp allows you to do interesting things with that. Like, building your own kinds of syntactic sugar.
Try Lisp. Common Lisp compilers usually generate faster code than Java (mostly because they compile to native code), yet you don't have to declare types unless you choose to do so. If you do, the compiler can use the declarations either to check type correctness or to generate optimize code, just as you wish.
Once you've experienced the freedom and flexibility of Lisp, there's no way back. Unfortunatly, you'll soon realize that this fact sucks hard when you try to program by library-shopping, scince there basically are no third-party libs for CL.
Java isn't strongly typed. It has static, or manifest, typing. Those two qualities are orthagonal.
In a strongly typed language, there are no cast operators, and hence no ClassCastExceptions. You don't have these even in dynamically-but-strongly typed languages, like Lisp or Python.
Java doesn't give you type safety, just type errors when you try to be smarter than the compiler, which isn't that hard. That is no surprise - it has been shown that proper type inference runs into the halting problem, by research on languages that at least try to be helpful rather than just annoying while maintaining static typing (like ML or Haskell). In this regard, Java combines the worst of both worlds, just like C and C++, even if it is otherwise better than them in almost everything.
Guy Steele did answer some questions on his role in Java development, most of it should be available on the web. IIRC, there were quite some things where he disagreed with Gosling, he likes to make it clear that his job was to document the language, not to design it.
BTW, what do you mean with "code metadata" being a feature of Lisp? In Lisp, code is data in a lot of interesting ways (like that Lisp code is expressed as Lisp lists, and can be manipulated as such using Macros, or that functions are objects that can be treated just like strings, passed around, stored in variables etc.), but - as a Lispnik - I don't see much data about this data anywhere. Are you talking about reflection/introspection?
As you say, refactoring relies on having good tests in the first place. Probably a code base that needs a rewrite hasn't been developed test-first up to now, or even in a test-friendly fashion, so that's a huge problem - coming up with good tests after the fact is a lot of error-prone (and boring) work.
It's probably still a better idea than to start from scratch, though. I seem to remember that someone announced a book on this subject (adding tests for legacy code) on the XP or test-driven mailing list, maybe the original poster should look there.
There is a DBC implementation for CLOS, the Common Lisp Object System. It doesn't require a preprocessor, of course, Lisp is flexible enough to do such a thing portably.
DBC-style assertions are also checked when the original method that asserted it is not run, but one that overrides it. For example, when you have a class A with a method doSomething that promises always to return an integer between 1 and 10, and a class B derived from A that overrides doSomething, you can be sure that you still get an integer between 1 and 10, while in C++, the assert()s would not run.
Scince a week or two, you can also use Debian instead of Redhat on FreeBSD. This is obviously way cooler than a less outdated version of RH. Take that, Puffy!;-)
Yes, these are great. Mine takes only 5 seconds, seems to be working well, and, the most important thing, I can hook it up to my computer:)
Now if anybody would release a glucose monitor that would include a JVM or something, like those neato cell phones, I would be the first to get one. Talk about gadget addict. Unfortunatly, allowing users to tweak things doesn't seem to be a high priority in the medical industry...
I'm SO tired of the "if you're not physically taking anything from them, it's not financially hurting them" argument.
But that's not what I said. I said that even if it's financially hurting them, and illegal as well, it's not stealing. It's still a crime, just a different one. If I kick you in your balls, it isn't murder either (or the other way around, I don't mean to imply that breaking copyright is automatically less severe than stealing), although I am physically hurting you in both cases.
I completely agree with everything you wrote, except for the last-but-one sentence (well, not that completly - let's say I consider it a valid point of view). I didn't say that breaking copyright is something good, or even tolerable - just that it's not theft, just like murder or selling drugs is not theft.
And I think the difference matters if we are to discuss such matters seriously, which unfortunatly neither of the involved sides seem to want most of the time.
God, how many times do we have to hear this stupid argument again.
Copying is not stealing. If you steal my car, I cannot drive it any more. If I copy a song, the original owner still can listen to it. Even if in both cases the victim sufferes financial losses, they are different - if I burn your house down, I'm still not a thief, even if you'd loose lots of money and other property because of it.
Not that "filesharing" would be legal, it's just that modern legal systems are advanced enough to feature more than one kind of crime.
For example, some implementations of malloc() have quite a noticable overhead, while allocating an object with a generational gc has an overhead of increasing one pointer. Additionally, you get better locality, and the order in which space is reclaimed is better suited for the real usage pattern than what human programmers tend to come up with, to the point that some objects may never be reclaimed, because it just wouldn't pay off enough.
What, not X100?
You could say the same about brainfuck, except that it isn't really slow.
The only part of Lisp where lists (and trees build of nested lists) play a vital role nowadays is manipulating Lisp programs, that indeed happen to be Lisp lists. I.e. Macros. Hard to call that a misfeature of Lisp, because about every language becomes a parse tree sometimes, it's just that Lisp allows you to do interesting things with that. Like, building your own kinds of syntactic sugar.
Once you've experienced the freedom and flexibility of Lisp, there's no way back. Unfortunatly, you'll soon realize that this fact sucks hard when you try to program by library-shopping, scince there basically are no third-party libs for CL.
In a strongly typed language, there are no cast operators, and hence no ClassCastExceptions. You don't have these even in dynamically-but-strongly typed languages, like Lisp or Python.
Java doesn't give you type safety, just type errors when you try to be smarter than the compiler, which isn't that hard. That is no surprise - it has been shown that proper type inference runs into the halting problem, by research on languages that at least try to be helpful rather than just annoying while maintaining static typing (like ML or Haskell). In this regard, Java combines the worst of both worlds, just like C and C++, even if it is otherwise better than them in almost everything.
BTW, what do you mean with "code metadata" being a feature of Lisp? In Lisp, code is data in a lot of interesting ways (like that Lisp code is expressed as Lisp lists, and can be manipulated as such using Macros, or that functions are objects that can be treated just like strings, passed around, stored in variables etc.), but - as a Lispnik - I don't see much data about this data anywhere. Are you talking about reflection/introspection?
As you say, refactoring relies on having good tests in the first place. Probably a code base that needs a rewrite hasn't been developed test-first up to now, or even in a test-friendly fashion, so that's a huge problem - coming up with good tests after the fact is a lot of error-prone (and boring) work.
It's probably still a better idea than to start from scratch, though. I seem to remember that someone announced a book on this subject (adding tests for legacy code) on the XP or test-driven mailing list, maybe the original poster should look there.
There is a DBC implementation for CLOS, the Common Lisp Object System. It doesn't require a preprocessor, of course, Lisp is flexible enough to do such a thing portably.
DBC-style assertions are also checked when the original method that asserted it is not run, but one that overrides it. For example, when you have a class A with a method doSomething that promises always to return an integer between 1 and 10, and a class B derived from A that overrides doSomething, you can be sure that you still get an integer between 1 and 10, while in C++, the assert()s would not run.
That's because it basically is ArgoUML, just non-free.
In fact, I doubt there is much you cannot do with Gnus, it's amazing. Be sure to check out http://my.gnus.org for lots of cool stuff.
Scince a week or two, you can also use Debian instead of Redhat on FreeBSD. This is obviously way cooler than a less outdated version of RH. Take that, Puffy! ;-)
Bah, who needs anti-spam consultants when the spammers are gone. I say, go for it!
Now if anybody would release a glucose monitor that would include a JVM or something, like those neato cell phones, I would be the first to get one. Talk about gadget addict. Unfortunatly, allowing users to tweak things doesn't seem to be a high priority in the medical industry...
And I think the difference matters if we are to discuss such matters seriously, which unfortunatly neither of the involved sides seem to want most of the time.
Copying is not stealing. If you steal my car, I cannot drive it any more. If I copy a song, the original owner still can listen to it. Even if in both cases the victim sufferes financial losses, they are different - if I burn your house down, I'm still not a thief, even if you'd loose lots of money and other property because of it.
Not that "filesharing" would be legal, it's just that modern legal systems are advanced enough to feature more than one kind of crime.
Yeah, welcome to the nineties, wintel kiddies!
Um, wait...
Don't read usenet much, do you?
Well, but their absolutely uncool URI design still sucks.