What else did you expect? The populace has been thoroughly disarmed, and now lies prostrate and helpless before the power of the State. The rulers no longer have to worry about the peasants rising up against their masters, so they have little need for restraint and caution anymore.
I have little good to say about Java myself, but apparently for different reasons than you. My beef with Java is that it's not very strongly typed -- you are continually throwing away type information by storing things in Object variables, then later doing error-prone downcasts to the type you want.
Why on earth do we need strong typing? Run-time efficiency is one nice benefit of strong typing, but perhaps a more important benefit is that strong typing helps you catch lots of errors before you ever even run your program.
> closure with a President with the
> qualifications of a head of lettuce is still
> closure
I prefer that to a president with the qualifications of a gangster. We've had eight years of evil/smart; at least evil/dumb will do less damage.
BTW, you seem to be accepting the sycophantic press's portrayal of Gore as some sort of great thinker. But from what I've read, he was quite a poor student in college and flunked out of several courses.
The problem with electronic voting is that there is no physical record, no physical evidence of the actual vote. This makes it great if your intent is to commit election fraud, but it's terrible if you want fair and honest elections. Furthermore, the source code for these systems is invariably a closely guarded secret. Finally, I think it is no coincidence that the maker of one popular electronic voting system (Shouptronic) just happens to be a man who has been convicted of election fraud...
Listen, India has far more voters than the US has, and they have no trouble manually counting every single ballot. We should do the same, to ensure that we have the proper checks in place to prevent election fraud. I know, you impatient children are whining that we won't have the election results by the evening of the same day we vote. So what? It's worth a little wait for results in order to ensure the integrity of the process.
> [Discussion about using multiple interfaces
> instead of const.]
See my comments in another branch of this thread. What you're proposing is much more awkward and a lot of work that most programmers won't do, and the designers of the JCL didn't do either. The const keyword is much, much, simpler and easier to use. I cannot for the life of me see why Java's designers thought they were doing anybody a favor by omitting "const" from the language.
> something far more powerful than templates:
> Interfaces
Not even close. Interfaces are not much different from an abstract base class in C++. Read Matt Austern's book _Generic Programming_, and you'll begin to see what templates can do that interfaces will never even come close to doing.
> If you have a set that you don't want changed,
> return copies of its objects. Don't return the
> orginals.
Yet this is not what the set class provided in the JCL does, which suggests that the distinction between a container of objects and a container of references is lost on the writers of the JCL, probably due to the fact that Java goes out of its way to disguise the fact that you only have references to objects, not the objects themselves.
> No, there is no guarantee [that finalize will
> be called] unless you do the following:
>
>...
> System.runFinalization();
> System.gc();
And that is absurdly impractical. That's just another explicit resource cleanup, which is what C++ destructors let you avoid.
> If you are going to avoid memory leaks in C++
> programs you need to call deconstructors
> explicitly anyway!
This is a truly bizarre statement. You NEVER have to call destructors explicitly -- in fact, you'd better not call them explicitly -- unless the object in question was created via placement new on raw memory. If you want to avoid memory leaks in C++, just stick to building on top of the standard container classes and a handful of smart pointer classes.
> I have rarely seen programmers beyond
> professors themselves that can make the ideas
> that you promote work.
WHICH ideas? Are you suggesting that a person needs a Ph.D. to use const correctly?
> [Lots of personal insults based on absolutely
> no knowledge of what I am actually like.]
You seem to have this blind spot that doesn't allow you to even conceive of the possibility of someone who doesn't like Java without being mentally defective. Just because I don't agree with you that Java is the solution to all the world's problems doesn't make me unadaptable, etc.
I think you need to grow up.
>> That's the beauty of real, honest-to-God
>> destructors: they get called automatically.
>
> Yep. And they work really well when you don't
> pass the object by reference and the
> deconstructor gets called with the stack
> cleanup. (Sucks, trust me.:-))
I'm not sure what you're talking about here, but I'm guessing that you're referring to what happens if you pass an rvalue (temporary object) to a function that takes a const reference parameter and assumes that this reference will continue to be valid after the function returns. If so, you're out of date. The ANSI/ISO standard redefined the lifetime of temporaries to take care of this.
> This late entry, combined with the goal of
> preserving its C forbearer, has led to
> inconsistent use of exceptions in C++ libraries.
Sounds like you're not up to date on the ANSI/ISO
C++ Standard (finalized in 1998). Exceptions
are consistently used throughout the standard
library.
> You also miss the boat somewhat on the const
> keyword.
As your comments show below, it looks like you still don't understand what const is all about.
> While not as syntactically convenient
> as const, Java interfaces can be used to
> provided mutable and immutable interfaces to
> your classes. This does, IMHO, a better
> job of separating the const methods from the
> non-const ones.
The point is that once you declare a method const, the compiler will make sure that the method body doesn't modify the object state somehow. Java has nothing like this safety check. Java seems to be big on performance-draining runtime error-checking, but weak on performance-neutral compile-time error-checking. And what's so superior about having to go to all the trouble of defining two separate interfaces to a class? This is enough work that it will deter a lot of programmers from bothering with it. The JCL itself doesn't do it. In comparison, sticking the keyword "const" at the end of a method declarations is trivially easy.
> The clean separation of inheritance of
> interface from inheritance of implementation in
> Java is way ahead of the C++ inheritance model
> where the two are muddled.
Sorry, but they're muddled in Java too, as you can use "extends" for both interface inheritance and implementation inheritance. In C++, public inheritance should really only be used for interface inheritance, and private inheritance for implementation inheritance.
> the freedom from memory leaks
This is a red herring from the early days when C++ lacked adequate libraries. Nowadays by using smart pointers, the standard container classes, and perhaps a few of your own container classes, memory leaks aren't a problem anymore, because you never deal with "bare" pointers.
> When you are done with your object, call dispose
And what if you forget to call dispose? Then you're hosed. That's the beauty of real, honest-to-God destructors: they get called automatically. You can't forget to call them. They are a very powerful tool for preventing yourself from even having the opportunity to make a mistake.
>> No real analog to const. The "final" keyword
>> only prevents assignment. It does not prevent
>> modification of the object referenced. [...]
>
> Why is this a problem? If you absolutely need
> a static class, use a static class.
This is a complete non sequitur. Do you have any idea of what const means in C++? I am not talking about whether objects of a nested class have access to the instance variables of the enclosing class, so static classes vs. inner classes have no bearing on the discussion. I am talking about being able to write declarations like this:
void foo(C const & x)
or
void bar(...) const
meaning that foo takes a reference parameter of type C, and is guaranteed not to modify the state of x, and that the method call z.bar(...) does not modify the state of z.
> As for docs, that's why there is that
> wonderful thing called JavaDocs that half
> the C++ industry has been trying to emulate.
Again, you completely miss the point or never tried to understand it. I have found, from many years of practical experience, that many errors arise from not being sure whether or not a method might modify the state of an object passed by reference. Javadoc doesn't help you if the person writing the code forgets to put in the necessary comments. But if you develop the reflex habit of always declaring methods to be const when they don't change the state of their object, and always making reference parameters be const if the method doesn't change the state of the parameter, then it is immediately clear what method calls have the potential to change the state of the objects on which they operate.
>> In a similar vein, no notion of a "const"
>> method. In fact, you can have a "final"
>> method, but its meaning bears absolutely no
>> relation to the use of "final" when applied to
>> variables.
>
> This is because you misunderstand the final
> keyword. In general, final means that the item
> cannot be overridden by an extending class.
> It produces a similar function with variables.
On the contrary, I understand exactly what final means. The use of "final" in
void foo() final
means what you say, but the use of "final" in
final int N = 37;
(which may appear in a method body) means something completely unrelated to the first use of "final" -- that you cannot change the value of N.
>> This results in situations [in Java] where code
>> outside of an associative container class
>> (like a set) can screw up the associative
>> container by modifying the state of objects
>> contained in that container.
>
> Huh? If you've got the object, you've got the
> object. You are free to modify it.
THAT'S THE PROBLEM! If you retrieve an object from a set, there are now references to the object within the set and in your code. If you modify the state of that object in your code, you've
can screw up the set, as its code depends on the states of the objects it contains not changing. The set container has no way of protecting itself from this kind of monkey-wrenching. If Java had an analog to const the implementation of a set container could partially protect itself by returning only const references to the objects it contains.
> in an Object container just by keeping a
> pointer to it. You aren't protecting yourself
> from didly.
In C++ you can protect yourself, because a set object stores *copies* of the objects inserted into it, and when you iterate over the elements of the set you can only get *const* references to the elements.
>> No reliable destructors, so you cannot use
>> the "resource acquisition is a constructor
>> and resource release is a destructor" idiom
>
> [Gives an example using finalize()]
> Damn! That looks like the resource will be
> closed just before the class is garbage
> collected!
You didn't read what I wrote, and you don't seem to know the very language you are promoting. Java does *NOT* guarantee that any particular unused object will *ever* be garbage-collected, so there is no guarantee that finalize() will ever be called! (It reclaims storage when it has to, but makes no guarantees beyond this.) Furthermore, even if the object is eventually garbage-collected, there is no way of knowing when that will happen. For many kinds of resources, it is not sufficient to know that the resource will be released at some indefinite point in the far future; you want it released as soon as you are done with it! A mutex is an example of just such a resource, and it was one of the examples; didn't you pay attention to what you read?
>> [Comments about templates in C++ and strong
>> typing.]
>
> You don't seem to realize that this is a
> double edged sword. If you enforce a type at
> all times, you can have no genericity.
It's clear from this comment that you have no clue as to how C++ templates work. The beauty of templates is that they give you both type-safety AND genericity at the same time. I have yet to see any other library that is as generic and flexible as the C++ Standard Template Library, and the STL does this without giving up efficiency in the process!
> You know, it's this type of acedemia that gets
> companies stuck with unmaintainable, buggy,
> non-customizable software.
This is ludicrous. You've never seen a line of code I've written, yet you're willing to call it "unmaintainable, buggy, and non-customizable." I spend a considerable amount of time worrying about maintainability and flexibility in my code, and I have always had very low error rates in my code. Here are some clues as to the quality of my work:
- My boss at MasPar described me as "one of the
most productive and accurate programmers I have
known."
- My NewsTracker daemon at Excite underwent a
significant change in architecture with nary a
hiccup. (It's called proper modularization.)
- My rearchitecture of one part of the C++
libraries used at Excite helped jumpstart
a couple of stalled projects (hint: I took
unmaintainable, non-customizable code and made
it maintainable and customizable).
- TenFold paid me six figures a year to work on
their core libraries.
- Every place I've worked for has been sorry to
see me go.
>> No reliable destructors, so you cannot use the
>> "resource acquisition is a constructor and
>> resource release is a destructor" idiom [...]
> You do not need to do it. Java never forgets to
> deallocate the resource anyway
That's taking a shortsighted view of what constitutes a resource. Memory isn't the only resource that is acquired or released. Here are some other examples:
- Opening and closing files. In C++ the destructor for an iostream flushes and closes the file -- and this happens as soon as the iostream object is deleted (if dynamically allocated) or goes out of scope. Contrast this with Java, where even if you do put cleanup code in a finalize method, the finalize method only gets executed when AND IF the garbage collector gets around to reclaiming the storage. (That's right. There is no guarantee that the finalize method will actually EVER be called.)
- Locking and unlocking a mutex. In C++, you can write a wrapper class for which the constructor locks a mutex and the destructor unlocks it. Thus, to protect a piece of code as a critical section, you just write
{
mutex_wrapper mw(the_mutex);
;
}
This way, no matter how you exit the critical section -- returning from the function, throwing an exception, whatever -- you cannot possibly forget to unlock the mutex when you leave.
> The java programmers have not decided that
> they are smarter, they were working with an
> agenda in mind. That agenda was to remove the
> reliance on such things as pointers which can
> kludge up code on different platforms.
First of all, the use of pointers has nothing to do with platform portability. Secondly, I find that I rarely use pointers when I write C++ -- by using the Standard Library container classes, my own container classes, and highly-efficient smart-pointer classes, I've found it possible to eliminate almost all of the problems people have with pointers.
Finally, I like C++ over Java for much the same reason I like Unix/Linux over Windows. With C++ and Unix, it's "have it your way". With Java and Windows, it's "have it Bill's way" (Bill Joy or Bill Gates).
> There are good reasons also to be object
> oriented fully in a languages nature - it
> teaches good programming practice.
I disagree. OOP has become something of an unexamined mantra, and people assume that OOP and good programming practice are the same thing. I would argue that OOP is a useful tool, but don't get so excited about your tools that you use them where they are not appropriate. Remember the old saw that "software engineering is a simple matter of finding the right wrench to pound in the right screw."
In particular, there is nothing virtuous about the object.function(args) syntax over the function(args) syntax. It's nothing more than a fetish. The most important contribution of OOP was support for abstract data types (hiding implementation details, providing limited interfaces). Inheritance is useful on occasion, but widely overused and abused. (For example, a lot of OOP enthusiasts think that code reuse and inheritance are synonymous.)
There's a good possibility that I'm the instructor being referred to. Before you call me a clueless academic, let me give you some of my creds:
- I've been programming for twenty years.
- Almost all of my work experience (including all of the last five years) has been in industry, doing hands-on programming.
- I built the NewsTracker service for Excite.
- I wrote about half of the microcode for the MasPar MP-1 series of massively-parallel computers.
- I'm willing to use my real name when posting my opinions, and not hide behind a pseudonym:-).
In my opinion, Java may be fine for applets, but it is utterly unsuitable for large software projects. I'm going to write up a comprehensive critique of Java sometime within the next few months, but for the moment, let me toss off a few problems that immediately come to mind:
- No real analog to const. The "final" keyword only prevents assignment. It does not prevent modification of the object referenced. I consider "const" correctness an important part of good program design, as it helps you catch many errors at compile time, and also acts as documentation for your code.
- In a similar vein, no notion of a "const" method. In fact, you can have a "final" method, but its meaning bears absolutely no relation to the use of "final" when applied to variables.
- No reliable destructors, so you cannot use the "resource acquisition is a constructor and resource release is a destructor" idiom that is so useful in C++. This idiom is useful because it allows you to remove opportunities for error from your program (you can't forget to release a resource).
- Java is a "police state" language, meaning that its designers have decided that they are smarter than everyone else, so they will dictate the programming style everyone has to use. For example, all functions must be class members, all exceptions that may be thrown (except for RuntimeException and Error) have to be declared with a throws clause, etc. There are good arguments against many of these decisions, in at least some circumstances.
The designers of C++, on the other hand, were a bit more humble. They left the language amenable to a variety of programming styles. This has allowed people to experiment to find out what really works, rather than being forced to accept some doctrine handed down from on high.
- The reference semantics combined with "by-value" syntax for objects cause a lot of confusion for beginners. The fact that you *only* have reference semantics for objects causes design problems. For example, there is a real conceptual and design difference between a container of objects and a container of references to objects, but Java mixes the two ideas together. This results in situations where code outside of an associative container class (like a set) can screw up the associative container by modifying the state of objects contained in that container.
- The lack of templates means that one loses some of the power of typechecking, and one has to resort to some pretty clumsy and awkward means of dealing with container classes. For example, in C++, I can have an associative array mapping keys of type K to values of type V, for any types K and V, through the use of templates. The analog in Java is a container that maps Object to Object. The problem here is that I have to do widening
conversions that weaken typing. Strong typing is important because it is an extremely useful tool for catching errors very early -- at compile time
-- instead of at run time, when they are harder to deal with. With Java I can no longer guarantee that all my keys have one type, and all my values
have one type. When I retrieve values, I have to do narrowing conversions, which may result in a run-time type error that I should have been able to catch at compile time. And what if I want to put values of a primitive type in a generic container? Then I have to resort to the truly
hideous kludge of using these wrapper classes to turn them into objects.
- The vast gulf in behavior and syntax between primitive types and object types is a nasty misfeature of the language that throws up barriers to writing generic code.
The fact that the Australian government is spitting on freedom of speech and tossing civil liberties in the trash can should surprise no one. After all, they just finished getting guns out of the hands of the general populace. The same thing is happening in the UK, where trial by jury is being phased out. The same kind of thing happened in Germany in the '30s, after they passed extensive gun control legislation. Governments understand and respect only raw force. Once the people are disarmed, the velvet glove comes off and the iron fist is revealed.
If you're going for a Ph.D., your choice of advisor is probably more important than your choice of school. Get familiar with the research literature in the areas that interest you. Find several researchers you'd like to work with. Find out if they are good mentors for their students, are able to take on a new graduate student, are good at getting funding for their students, etc. Then apply to the schools where your best prospective graduate advisors are.
> I really hope that we're not at the > point where open source and free software > eclipse innovative products just because they > aren't Open Source(TM).
But that's always the way it's been. The markets hate proprietary technology. No company likes to be held hostage to a monopoly provider. VHS won out over Beta, even though Beta was a superior technology introduced a year before VHS, simply because VHS was non-proprietary. The Mac lost out to the PC, in spite of its superior technology, because it also was closed, proprietary technology, whereas the PC was open.
The one apparent exception to this is Windows, but that appears to be a temporary phenomenon. I fully expect Windows NT and it successors to be nothing bad a bad memory in five years. Windows might still have a presence on the desktop, but I think it will have disappeared from servers.
> Any group with enough of a desire can skew test > results of their product by twisting statistics. > Remember almost all statistics are filtered > through Confidence Intervals, for the purpose > of hypothesis testing. It could be that one > group is using a 90% confidence interval, while > another is using a 99% confidence interval. The > problem of this is the eternal problem of the > statistician: balancing Type I and Type II > errors; one is about including more than you > should, and one is about excluding > what should rightfully be there.
It's the eternal problem of the orthodox statistician, but not of the Bayesian statistician. The problems you mention -- and many, many other problems with orthodox statistics -- simply disappear when you use Bayesian statistics. What's ironic about this whole situation is that orthodox statistics has all these subjective choices that can greatly alter the outcome of your analysis, as a result of its efforts to be supposedly more objective by avoiding the prior distributions used by Bayesians.
In fact, I am continually amazed that orthodox statistics is still taught at all, for two reasons:
- Over 50 years ago, Cox proved that any system for reasoning about degrees of plausibility that is not equivalent to Bayesian methods is either logically inconsistent, or it exhibits pathological and clearly wrong behavior on simple examples.
- Over 20 years ago, E. T. Jaynes horrified a group of applied statisticians by showing a simple example of how the methods of orthodox statistics could produce a confidence interval that lies entirely outside the range of logically possible values for the parameter! (Thus, orthodox statistics is logically inconsistent.)
Anybody who's interested in how to do statistics *right* should read Jaynes' book, _Probability Theory: the Logic of Science_, a preliminary version of which you can download by following links from http://bayes.wustl.edu.
Take a look at www.openspeech.org in a month or two. I'm working on putting together an open source speech recognition toolkit for Linux. I'd appreciate hearing from people on what particular speech apps they're most interested in, and whether they'd be interested in trading programming for instruction (i.e., if you write code for the project, I'll teach you about probability theory and speech recognition.)
Also, I'm interested in ideas for collecting training data. At present there are few, if any, *free* corpora of training data. Both text corpora (for training language models, i.e., what kinds of word sequences are plausible) and acoustic corpora (collections of recorded utterances, along with transcriptions) are needed. One possibility, that would be useful for training models to be used in command applications on desktop computers, would be to ask people to record snippets of speech on their own computers, and donate these to the project.
One would think that if you had actually read the article and disagreed with it, you would tell us which particular arguments of Tucker's you find fault with, and why. So let me dissect your comments, and tell you just what I find wrong with them.
> These are all socialistic concepts. [...] > Capitalism is just fine by me. Free market [...]
As a matter of fact, I suspect that I am a rather more consistent supporter of free markets than you are. I am a free-market anarchist. I don't believe in socialized medicine, socialized education, socialized transportation (State-owned roads), socialized jurisprudence (State-controlled monopoly courts), nor socialized crime control (State-controlled monopoly police).
> If I spend my free time developing a product, > or idea, that others want, I should damn well > be able to charge them a compensatory fee.
Nobody's saying that you have to give anybody information for free. But IP (intellectual property) supporters make the astounding claim that you have the right to forcibly prevent other people from making use of information they have acquired, in the absence of any contractual obligation.
> the first time someone tries to TAKE something > I have developed myself,
Here is where the analogy with concrete things breaks down completely. If I use an idea that you thought of, or make a copy of a program you wrote, book you wrote, painting you produced, etc., I HAVE TAKEN NOTHING FROM YOU -- you still have exactly what you had before. Unless I whack you over the head and/or steal or destroy some *physical* property of yours, I CANNOT TAKE INFORMATION OR IDEAS FROM YOU. In stark contrast to concrete things, ideas and information are infinitely replicable.
At this point you may argue that you are deprived of the benefit you would have received by controlling all use of your idea. In other words, you are deprived of the benefits of a monopoly. Tough. Coca Cola loses billions every year to competing companies because it is deprived of the benefits of a beverage monopoly.
> Why should I be forced to give away not only > the binaries for an application I develop, but > also the source code?
Nobody's forcing you to do anything. It's the IP advocates who want to use force against people. If you're thinking of the GPL, the irony here is that the GPL only has power to make you give out source code (absent an explicit contract) if you accept the notions of intellectual property and copyright. Only if we discard the notion of IP are you freed from the obligation to make source code available when you modify a GPL'ed work (unless you've entered into an explicit contract to do so.)
What else did you expect? The populace has been thoroughly disarmed, and now lies prostrate and helpless before the power of the State. The rulers no longer have to worry about the peasants rising up against their masters, so they have little need for restraint and caution anymore.
I have little good to say about Java myself, but apparently for different reasons than you. My beef with Java is that it's not very strongly typed -- you are continually throwing away type information by storing things in Object variables, then later doing error-prone downcasts to the type you want.
Why on earth do we need strong typing? Run-time efficiency is one nice benefit of strong typing, but perhaps a more important benefit is that strong typing helps you catch lots of errors before you ever even run your program.
> closure with a President with the
> qualifications of a head of lettuce is still
> closure
I prefer that to a president with the qualifications of a gangster. We've had eight years of evil/smart; at least evil/dumb will do less damage.
BTW, you seem to be accepting the sycophantic press's portrayal of Gore as some sort of great thinker. But from what I've read, he was quite a poor student in college and flunked out of several courses.
The problem with electronic voting is that there is no physical record, no physical evidence of the actual vote. This makes it great if your intent is to commit election fraud, but it's terrible if you want fair and honest elections. Furthermore, the source code for these systems is invariably a closely guarded secret. Finally, I think it is no coincidence that the maker of one popular electronic voting system (Shouptronic) just happens to be a man who has been convicted of election fraud...
Listen, India has far more voters than the US has, and they have no trouble manually counting every single ballot. We should do the same, to ensure that we have the proper checks in place to prevent election fraud. I know, you impatient children are whining that we won't have the election results by the evening of the same day we vote. So what? It's worth a little wait for results in order to ensure the integrity of the process.
> [Discussion about using multiple interfaces
...
> instead of const.]
See my comments in another branch of this thread. What you're proposing is much more awkward and a lot of work that most programmers won't do, and the designers of the JCL didn't do either. The const keyword is much, much, simpler and easier to use. I cannot for the life of me see why Java's designers thought they were doing anybody a favor by omitting "const" from the language.
> something far more powerful than templates:
> Interfaces
Not even close. Interfaces are not much different from an abstract base class in C++. Read Matt Austern's book _Generic Programming_, and you'll begin to see what templates can do that interfaces will never even come close to doing.
> If you have a set that you don't want changed,
> return copies of its objects. Don't return the
> orginals.
Yet this is not what the set class provided in the JCL does, which suggests that the distinction between a container of objects and a container of references is lost on the writers of the JCL, probably due to the fact that Java goes out of its way to disguise the fact that you only have references to objects, not the objects themselves.
> No, there is no guarantee [that finalize will
> be called] unless you do the following:
>
>
> System.runFinalization();
> System.gc();
And that is absurdly impractical. That's just another explicit resource cleanup, which is what C++ destructors let you avoid.
> If you are going to avoid memory leaks in C++
> programs you need to call deconstructors
> explicitly anyway!
This is a truly bizarre statement. You NEVER have to call destructors explicitly -- in fact, you'd better not call them explicitly -- unless the object in question was created via placement new on raw memory. If you want to avoid memory leaks in C++, just stick to building on top of the standard container classes and a handful of smart pointer classes.
> I have rarely seen programmers beyond
> professors themselves that can make the ideas
> that you promote work.
WHICH ideas? Are you suggesting that a person needs a Ph.D. to use const correctly?
> [Lots of personal insults based on absolutely
> no knowledge of what I am actually like.]
You seem to have this blind spot that doesn't allow you to even conceive of the possibility of someone who doesn't like Java without being mentally defective. Just because I don't agree with you that Java is the solution to all the world's problems doesn't make me unadaptable, etc.
I think you need to grow up.
>> That's the beauty of real, honest-to-God :-))
>> destructors: they get called automatically.
>
> Yep. And they work really well when you don't
> pass the object by reference and the
> deconstructor gets called with the stack
> cleanup. (Sucks, trust me.
I'm not sure what you're talking about here, but I'm guessing that you're referring to what happens if you pass an rvalue (temporary object) to a function that takes a const reference parameter and assumes that this reference will continue to be valid after the function returns. If so, you're out of date. The ANSI/ISO standard redefined the lifetime of temporaries to take care of this.
> This late entry, combined with the goal of
> preserving its C forbearer, has led to
> inconsistent use of exceptions in C++ libraries.
Sounds like you're not up to date on the ANSI/ISO
C++ Standard (finalized in 1998). Exceptions
are consistently used throughout the standard
library.
> You also miss the boat somewhat on the const
> keyword.
As your comments show below, it looks like you still don't understand what const is all about.
> While not as syntactically convenient
> as const, Java interfaces can be used to
> provided mutable and immutable interfaces to
> your classes. This does, IMHO, a better
> job of separating the const methods from the
> non-const ones.
The point is that once you declare a method const, the compiler will make sure that the method body doesn't modify the object state somehow. Java has nothing like this safety check. Java seems to be big on performance-draining runtime error-checking, but weak on performance-neutral compile-time error-checking. And what's so superior about having to go to all the trouble of defining two separate interfaces to a class? This is enough work that it will deter a lot of programmers from bothering with it. The JCL itself doesn't do it. In comparison, sticking the keyword "const" at the end of a method declarations is trivially easy.
> The clean separation of inheritance of
> interface from inheritance of implementation in
> Java is way ahead of the C++ inheritance model
> where the two are muddled.
Sorry, but they're muddled in Java too, as you can use "extends" for both interface inheritance and implementation inheritance. In C++, public inheritance should really only be used for interface inheritance, and private inheritance for implementation inheritance.
> the freedom from memory leaks
This is a red herring from the early days when C++ lacked adequate libraries. Nowadays by using smart pointers, the standard container classes, and perhaps a few of your own container classes, memory leaks aren't a problem anymore, because you never deal with "bare" pointers.
> When you are done with your object, call dispose
And what if you forget to call dispose? Then you're hosed. That's the beauty of real, honest-to-God destructors: they get called automatically. You can't forget to call them. They are a very powerful tool for preventing yourself from even having the opportunity to make a mistake.
>> No real analog to const. The "final" keyword
>> only prevents assignment. It does not prevent
>> modification of the object referenced. [...]
>
> Why is this a problem? If you absolutely need
> a static class, use a static class.
This is a complete non sequitur. Do you have any idea of what const means in C++? I am not talking about whether objects of a nested class have access to the instance variables of the enclosing class, so static classes vs. inner classes have no bearing on the discussion. I am talking about being able to write declarations like this:
void foo(C const & x)
or
void bar(...) const
meaning that foo takes a reference parameter of type C, and is guaranteed not to modify the state of x, and that the method call z.bar(...) does not modify the state of z.
> As for docs, that's why there is that
> wonderful thing called JavaDocs that half
> the C++ industry has been trying to emulate.
Again, you completely miss the point or never tried to understand it. I have found, from many years of practical experience, that many errors arise from not being sure whether or not a method might modify the state of an object passed by reference. Javadoc doesn't help you if the person writing the code forgets to put in the necessary comments. But if you develop the reflex habit of always declaring methods to be const when they don't change the state of their object, and always making reference parameters be const if the method doesn't change the state of the parameter, then it is immediately clear what method calls have the potential to change the state of the objects on which they operate.
>> In a similar vein, no notion of a "const"
>> method. In fact, you can have a "final"
>> method, but its meaning bears absolutely no
>> relation to the use of "final" when applied to
>> variables.
>
> This is because you misunderstand the final
> keyword. In general, final means that the item
> cannot be overridden by an extending class.
> It produces a similar function with variables.
On the contrary, I understand exactly what final means. The use of "final" in
void foo() final
means what you say, but the use of "final" in
final int N = 37;
(which may appear in a method body) means something completely unrelated to the first use of "final" -- that you cannot change the value of N.
>> This results in situations [in Java] where code
>> outside of an associative container class
>> (like a set) can screw up the associative
>> container by modifying the state of objects
>> contained in that container.
>
> Huh? If you've got the object, you've got the
> object. You are free to modify it.
THAT'S THE PROBLEM! If you retrieve an object from a set, there are now references to the object within the set and in your code. If you modify the state of that object in your code, you've
can screw up the set, as its code depends on the states of the objects it contains not changing. The set container has no way of protecting itself from this kind of monkey-wrenching. If Java had an analog to const the implementation of a set container could partially protect itself by returning only const references to the objects it contains.
> in an Object container just by keeping a
> pointer to it. You aren't protecting yourself
> from didly.
In C++ you can protect yourself, because a set object stores *copies* of the objects inserted into it, and when you iterate over the elements of the set you can only get *const* references to the elements.
>> No reliable destructors, so you cannot use
>> the "resource acquisition is a constructor
>> and resource release is a destructor" idiom
>
> [Gives an example using finalize()]
> Damn! That looks like the resource will be
> closed just before the class is garbage
> collected!
You didn't read what I wrote, and you don't seem to know the very language you are promoting. Java does *NOT* guarantee that any particular unused object will *ever* be garbage-collected, so there is no guarantee that finalize() will ever be called! (It reclaims storage when it has to, but makes no guarantees beyond this.) Furthermore, even if the object is eventually garbage-collected, there is no way of knowing when that will happen. For many kinds of resources, it is not sufficient to know that the resource will be released at some indefinite point in the far future; you want it released as soon as you are done with it! A mutex is an example of just such a resource, and it was one of the examples; didn't you pay attention to what you read?
>> [Comments about templates in C++ and strong
>> typing.]
>
> You don't seem to realize that this is a
> double edged sword. If you enforce a type at
> all times, you can have no genericity.
It's clear from this comment that you have no clue as to how C++ templates work. The beauty of templates is that they give you both type-safety AND genericity at the same time. I have yet to see any other library that is as generic and flexible as the C++ Standard Template Library, and the STL does this without giving up efficiency in the process!
> You know, it's this type of acedemia that gets
> companies stuck with unmaintainable, buggy,
> non-customizable software.
This is ludicrous. You've never seen a line of code I've written, yet you're willing to call it "unmaintainable, buggy, and non-customizable." I spend a considerable amount of time worrying about maintainability and flexibility in my code, and I have always had very low error rates in my code. Here are some clues as to the quality of my work:
- My boss at MasPar described me as "one of the
most productive and accurate programmers I have
known."
- My NewsTracker daemon at Excite underwent a
significant change in architecture with nary a
hiccup. (It's called proper modularization.)
- My rearchitecture of one part of the C++
libraries used at Excite helped jumpstart
a couple of stalled projects (hint: I took
unmaintainable, non-customizable code and made
it maintainable and customizable).
- TenFold paid me six figures a year to work on
their core libraries.
- Every place I've worked for has been sorry to
see me go.
One other comment I forgot to make:
> Exceptions are a good way of determining that
> something illegal has happened without knocking
> out the entire app.
Yes, of course. That is why C++ has had exceptions since before Java was released to the world.
>> No reliable destructors, so you cannot use the
>> "resource acquisition is a constructor and
>> resource release is a destructor" idiom [...]
> You do not need to do it. Java never forgets to
> deallocate the resource anyway
That's taking a shortsighted view of what constitutes a resource. Memory isn't the only resource that is acquired or released. Here are some other examples:
- Opening and closing files. In C++ the destructor for an iostream flushes and closes the file -- and this happens as soon as the iostream object is deleted (if dynamically allocated) or goes out of scope. Contrast this with Java, where even if you do put cleanup code in a finalize method, the finalize method only gets executed when AND IF the garbage collector gets around to reclaiming the storage. (That's right. There is no guarantee that the finalize method will actually EVER be called.)
- Locking and unlocking a mutex. In C++, you can write a wrapper class for which the constructor locks a mutex and the destructor unlocks it. Thus, to protect a piece of code as a critical section, you just write
{
mutex_wrapper mw(the_mutex);
;
}
This way, no matter how you exit the critical section -- returning from the function, throwing an exception, whatever -- you cannot possibly forget to unlock the mutex when you leave.
> The java programmers have not decided that
> they are smarter, they were working with an
> agenda in mind. That agenda was to remove the
> reliance on such things as pointers which can
> kludge up code on different platforms.
First of all, the use of pointers has nothing to do with platform portability. Secondly, I find that I rarely use pointers when I write C++ -- by using the Standard Library container classes, my own container classes, and highly-efficient smart-pointer classes, I've found it possible to eliminate almost all of the problems people have with pointers.
Finally, I like C++ over Java for much the same reason I like Unix/Linux over Windows. With C++ and Unix, it's "have it your way". With Java and Windows, it's "have it Bill's way" (Bill Joy or Bill Gates).
> There are good reasons also to be object
> oriented fully in a languages nature - it
> teaches good programming practice.
I disagree. OOP has become something of an unexamined mantra, and people assume that OOP and good programming practice are the same thing. I would argue that OOP is a useful tool, but don't get so excited about your tools that you use them where they are not appropriate. Remember the old saw that "software engineering is a simple matter of finding the right wrench to pound in the right screw."
In particular, there is nothing virtuous about the object.function(args) syntax over the function(args) syntax. It's nothing more than a fetish. The most important contribution of OOP was support for abstract data types (hiding implementation details, providing limited interfaces). Inheritance is useful on occasion, but widely overused and abused. (For example, a lot of OOP enthusiasts think that code reuse and inheritance are synonymous.)
There's a good possibility that I'm the instructor being referred to. Before you call me a clueless academic, let me give you some of my creds:
:-).
- I've been programming for twenty years.
- Almost all of my work experience (including all of the last five years) has been in industry, doing hands-on programming.
- I built the NewsTracker service for Excite.
- I wrote about half of the microcode for the MasPar MP-1 series of massively-parallel computers.
- I'm willing to use my real name when posting my opinions, and not hide behind a pseudonym
In my opinion, Java may be fine for applets, but it is utterly unsuitable for large software projects. I'm going to write up a comprehensive critique of Java sometime within the next few months, but for the moment, let me toss off a few problems that immediately come to mind:
- No real analog to const. The "final" keyword only prevents assignment. It does not prevent modification of the object referenced. I consider "const" correctness an important part of good program design, as it helps you catch many errors at compile time, and also acts as documentation for your code.
- In a similar vein, no notion of a "const" method. In fact, you can have a "final" method, but its meaning bears absolutely no relation to the use of "final" when applied to variables.
- No reliable destructors, so you cannot use the "resource acquisition is a constructor and resource release is a destructor" idiom that is so useful in C++. This idiom is useful because it allows you to remove opportunities for error from your program (you can't forget to release a resource).
- Java is a "police state" language, meaning that its designers have decided that they are smarter than everyone else, so they will dictate the programming style everyone has to use. For example, all functions must be class members, all exceptions that may be thrown (except for RuntimeException and Error) have to be declared with a throws clause, etc. There are good arguments against many of these decisions, in at least some circumstances.
The designers of C++, on the other hand, were a bit more humble. They left the language amenable to a variety of programming styles. This has allowed people to experiment to find out what really works, rather than being forced to accept some doctrine handed down from on high.
- The reference semantics combined with "by-value" syntax for objects cause a lot of confusion for beginners. The fact that you *only* have reference semantics for objects causes design problems. For example, there is a real conceptual and design difference between a container of objects and a container of references to objects, but Java mixes the two ideas together. This results in situations where code outside of an associative container class (like a set) can screw up the associative container by modifying the state of objects contained in that container.
- The lack of templates means that one loses some of the power of typechecking, and one has to resort to some pretty clumsy and awkward means of dealing with container classes. For example, in C++, I can have an associative array mapping keys of type K to values of type V, for any types K and V, through the use of templates. The analog in Java is a container that maps Object to Object. The problem here is that I have to do widening
conversions that weaken typing. Strong typing is important because it is an extremely useful tool for catching errors very early -- at compile time
-- instead of at run time, when they are harder to deal with. With Java I can no longer guarantee that all my keys have one type, and all my values
have one type. When I retrieve values, I have to do narrowing conversions, which may result in a run-time type error that I should have been able to catch at compile time. And what if I want to put values of a primitive type in a generic container? Then I have to resort to the truly
hideous kludge of using these wrapper classes to turn them into objects.
- The vast gulf in behavior and syntax between primitive types and object types is a nasty misfeature of the language that throws up barriers to writing generic code.
The fact that the Australian government is spitting on freedom of speech and tossing civil liberties in the trash can should surprise no one. After all, they just finished getting guns out of the hands of the general populace. The same thing is happening in the UK, where trial by jury is being phased out. The same kind of thing happened in Germany in the '30s, after they passed extensive gun control legislation. Governments understand and respect only raw force. Once the people are disarmed, the velvet glove comes off and the iron fist is revealed.
If you're going for a Ph.D., your choice of advisor is probably more important than your choice of school. Get familiar with the research literature in the areas that interest you. Find several researchers you'd like to work with. Find out if they are good mentors for their students, are able to take on a new graduate student, are good at getting funding for their students, etc. Then apply to the schools where your best prospective graduate advisors are.
> I really hope that we're not at the
> point where open source and free software
> eclipse innovative products just because they
> aren't Open Source(TM).
But that's always the way it's been. The markets hate proprietary technology. No company likes to be held hostage to a monopoly provider. VHS won out over Beta, even though Beta was a superior technology introduced a year before VHS, simply because VHS was non-proprietary. The Mac lost out to the PC, in spite of its superior technology, because it also was closed, proprietary technology, whereas the PC was open.
The one apparent exception to this is Windows, but that appears to be a temporary phenomenon. I fully expect Windows NT and it successors to be nothing bad a bad memory in five years. Windows might still have a presence on the desktop, but I think it will have disappeared from servers.
> Any group with enough of a desire can skew test
> results of their product by twisting statistics.
> Remember almost all statistics are filtered
> through Confidence Intervals, for the purpose
> of hypothesis testing. It could be that one
> group is using a 90% confidence interval, while
> another is using a 99% confidence interval. The
> problem of this is the eternal problem of the
> statistician: balancing Type I and Type II
> errors; one is about including more than you
> should, and one is about excluding
> what should rightfully be there.
It's the eternal problem of the orthodox statistician, but not of the Bayesian statistician. The problems you mention -- and many, many other problems with orthodox statistics -- simply disappear when you use Bayesian statistics. What's ironic about this whole situation is that orthodox statistics has all these subjective choices that can greatly alter the outcome of your analysis, as a result of its efforts to be supposedly more objective by avoiding the prior distributions used by Bayesians.
In fact, I am continually amazed that orthodox statistics is still taught at all, for two reasons:
- Over 50 years ago, Cox proved that any system for reasoning about degrees of plausibility that is not equivalent to Bayesian methods is either logically inconsistent, or it exhibits pathological and clearly wrong behavior on simple
examples.
- Over 20 years ago, E. T. Jaynes horrified a group of applied statisticians by showing a simple example of how the methods of orthodox statistics could produce a confidence interval that lies entirely outside the range of logically possible values for the parameter! (Thus, orthodox statistics is logically inconsistent.)
Anybody who's interested in how to do statistics *right* should read Jaynes' book, _Probability Theory: the Logic of Science_, a preliminary version of which you can download by following links from http://bayes.wustl.edu.
Take a look at www.openspeech.org in a month or two. I'm working on putting together an open source speech recognition toolkit for Linux. I'd appreciate hearing from people on what particular speech apps they're most interested in, and whether they'd be interested in trading programming for instruction (i.e., if you write code for the project, I'll teach you about probability theory and speech recognition.)
Also, I'm interested in ideas for collecting training data. At present there are few, if any, *free* corpora of training data. Both text corpora (for training language models, i.e., what kinds of word sequences are plausible) and acoustic corpora (collections of recorded utterances, along with transcriptions) are needed. One possibility, that would be useful for training models to be used in command applications on desktop computers, would be to ask people to record snippets of speech on their own computers, and donate these to the project.
One would think that if you had actually read the article and disagreed with it, you would tell us which particular arguments of Tucker's you find fault with, and why. So let me dissect your comments, and tell you just what I find wrong with them.
> These are all socialistic concepts. [...]
> Capitalism is just fine by me. Free market [...]
As a matter of fact, I suspect that I am a rather more consistent supporter of free markets than you are. I am a free-market anarchist. I don't believe in socialized medicine, socialized education, socialized transportation (State-owned roads), socialized jurisprudence (State-controlled monopoly courts), nor socialized crime control (State-controlled monopoly police).
> If I spend my free time developing a product,
> or idea, that others want, I should damn well
> be able to charge them a compensatory fee.
Nobody's saying that you have to give anybody information for free. But IP (intellectual property) supporters make the astounding claim that you have the right to forcibly prevent other people from making use of information they have acquired, in the absence of any contractual obligation.
> the first time someone tries to TAKE something
> I have developed myself,
Here is where the analogy with concrete things breaks down completely. If I use an idea that you thought of, or make a copy of a program you wrote, book you wrote, painting you produced, etc., I HAVE TAKEN NOTHING FROM YOU -- you still have exactly what you had before. Unless I whack you over the head and/or steal or destroy some *physical* property of yours, I CANNOT TAKE INFORMATION OR IDEAS FROM YOU. In stark contrast to concrete things, ideas and information are infinitely replicable.
At this point you may argue that you are deprived of the benefit you would have received by controlling all use of your idea. In other words, you are deprived of the benefits of a monopoly. Tough. Coca Cola loses billions every year to competing companies because it is deprived of the benefits of a beverage monopoly.
> Why should I be forced to give away not only
> the binaries for an application I develop, but
> also the source code?
Nobody's forcing you to do anything. It's the IP advocates who want to use force against people. If you're thinking of the GPL, the irony here is that the GPL only has power to make you give out source code (absent an explicit contract) if you accept the notions of intellectual property and copyright. Only if we discard the notion of IP are you freed from the obligation to make source code available when you modify a GPL'ed work (unless you've entered into an explicit contract to do so.)