If it's "what I do" which is the important factor, then an analogy may help: Someone who builds bridges or office towers is doing civil engineering. Someone who builds cubby houses is not. 7/8 of the world's "coders", as you say, build the software equivalent of cubby houses. I currently work on a 1.5 MLOC C++ project, which is probably the software equivalent of a 30 storey highrise (i.e. not on the scale of the Sears Tower, but fairly complex as these things go).
So even though I don't have an engineering degree proper (mine is CS), I feel like I'm doing engineering. Does that make me an "engineer"? I honestly don't know.
For the record, I have done "coding" for a living, or perhaps "development" at best. I can definitely tell the difference.
For desktop systems, responsiveness is far more important than raw speed - but Sun is in the server business, in which desktop-style responsiveness is less important.
That's true, but threads are just as important on the server. With the exception of serving read-only data (e.g. web servers, DNS servers), server applications rarely fit into the independent-address-space model. As soon as a client can modify state that others may want (and assuming you need multiprocessor scalability, of course) threads are precisely what you need.
Multiple threads make software hard to develop (and to debug and test).
You have to remember, though, that threads are there to help solve difficult problems. Such software is hard to develop and debug and test no matter what solution you use.
But the claim that C somehow can't accomplish everything is kind of silly. It may not always be the best choice (although it often is) but it is never impotent. If you could come up with a problem that is *impossible* to solve in C I would be very interested to hear about it.
That's not what the anonymous poster said. They said that C and discipline are not always adequate. C can accomplish anything in the same way that it's possible to use Roman numerals for any number-representation task. That doesn't mean it's an adequate solution. If it costs significantly more to develop the same product for equivalent robustness, performance and functionality in C compared to C++ (or PHP, or whatever), then C is not a more appropriate tool. If it costs prohibitively more, then C is not an adequate tool.
The problem is that there are no good studies which compare the effect of language on development sufficiently to convince everyone, so it's all down to extrapolation and anecdote. There are studies, for example, which show that an average programmer produces so many KLOC per year no matter what the language used, and since 1KLOC of C++ generally does more than 1KLOC of C, C++ is more productive. There are small-scale studies which seem to show that the higher-level the language, the faster you can produce a working product. However, nobody has yet tried getting multiple development teams to develop a medium-to-large scale product in more than one language and see what happens in terms of robustness, efficiency, functionality and development cost.
Speaking from my own experience, I find people using the same arguments against C++ that I used to use... until I actually worked on a large system written in C++. Now I always choose C++ over C unless there is a very compelling reason to do so, like binary compatibility with a legacy system.
Yes. Some have mentioned some reasons for this. I'll mention a one more.
Warning: long rambling post follows.
Like software development, animated filmmaking goes through a "pipeline", which is different for each animation medium. Also like software development, fixing problems earlier in the pipeline is much cheaper than fixing it later. So, for example, fixing an issue on the storyboards is going to be much cheaper than re-animating it.
The specific problem with 3D puppet animation is that fixing problems late in the process is even more expensive than in other kinds of animation.
Take traditional 2D animation, for example. The pipeline looks something like this:
Story (i.e. script and storyboards)
Layout (camera placement and staging)
Key animation
Breakdown/inbetweening
Clean-up
Ink & paint
At each stage after storyboarding, the work in progress is "filmed" and, when accepted by the supervisor of whoever is doing it, edited into the film. This is a very important part of the process because it ensures that everything is on the right track. You can usually work out from the key animation "pencil tests" if there are problems in the timing, for example. Then you only need to redo that, then go on to the next phase. If something does need to be fixed, you can often do that by redoing only those drawings that have problems.
The process of testing, redoing and re-testing is inherent in traditional animation. It's very similar with 3D computer animation, too. Everyone has a workstation with OpenGL hardware, so they can watch the action without going through the full render pipeline to see if it works or not. Once they've got it right, they can use that and go onto the next stage.
3D puppet animation is the "hardest" kind of animation from the perspective of testing. Naturally a lot of work goes into pre-visualisation in order to iron out problems early. The animators film themselves going through the pantomime actions in order to work out timing and so on. Computer graphics are used to rehearse camera movements on virtual 3D sets. Once you're done with that, though, it comes down to a physical 3D set with physical lights and physical puppets. If a problem is found here, you can't fix a few drawings and re-paint, or fix a few keyframes and re-render. You may be able to animate some other element and digitally composite it into the final plates, but in general, you have to redo the entire shot.
To complicate things further, in 3D puppet animation, you generally have to shoot the shot from start to finish. Traditional animators (and computer animators) can start with keys in the middle if they want. When you're animating dialogue, you often start with the most emphasised syllable in the line, for example. So you'd better make sure that you start any secondary actions which need to happen early otherwise you need to start all over again.
Of course "it's hard" isn't really an excuse. Good animators should be able to do all this. The trouble is that good animators are hard to find. Film schools don't teach what Aardman has had to find out over the last 20 years by trial and error. Chicken Run only had something like six key animators who were good enough to do the job and as such only had six sets filming concurrently. In feature animation terms, that's a very small amount of concurrency.
There's a key feature of Id's release scheme that you have to take into account, though. You can't take what Id has released and create a fully functioning Quake. That's because although they have released the source, they have not released the level files which make the game.
That way, they can still sell the game (as part of a bargain anthology or something) if and when they want to.
Oracle doesn't have "automatic" redundancy, or at least not in the sense you mean. You still need to code your application to handle servers which appear and disappear. While it may be "automatic", it's not "transparent".
For a developer porting applications from Unix to Linux, the number one feature I find missing is true Posix threads. This is happening RSN, I believe.
The ability to run C++ destructors on a cancelled thread (Solaris does this, at least) would also be a big help.
There are a few small things which make Linux slightly worse than it otherwise might be, such as proper cache coloring, but this isn't really missing functionality.
Disclaimer: I work in text retrieval for a living.
And the claim that vector search is faster than a database search is true, for as long as you can fit all the document vectors into RAM.
This is not true.
Recent research has shown it's quicker to access a compressed inverted file than it is to access an uncompressed inverted file, even if the whole index fits in RAM, provided your compression method is fast on your processor.
The reason for this counter-intuitive result is entirely due to cache performance. For a vector search, say, you have to consult the whole index, so your working set is the whole memory. For an inverted file-based search, you only need to consult the terms of interest. Not only is your working set much smaller, it's mostly accessing contiguous blocks of memory in a coherent manner.
I agree. Back to pre-Chaucer English for everyone!
(Someone with more knowledge of Old English than I is probably going to make a terribly funny joke about Beowulf clusters now. I just want to get in first.)
Didn't you read it? He writes his CGI in C++, so of course he doesn't debug using printf(). Clearly using iostreams is a far superior solution for his application.
The main reasons why studios are switching to Linux is that a) it's sufficiently similar to IRIX that programs port fairly easily (Unix + X11 + OpenGL is pretty portable), and b) you can now get decent hardware (e.g. OpenGL-enabled graphics hardware for previewing) for much less money.
...just about every area of mathematics that a typical CS undergrad learns is going to come in handy some day.
Take, for example, predicate logic. Most of the time, you don't need it. Until, that is, you have complicated business rules to enforce in your program, at which point the best solution is often to encode the rules as axioms and write a theorem prover (or write this part in a logic language, such as Prolog or Mercury, but you still need a grounding in predicate logic in order to use a logic language). Theorem proving also turns up a lot in compilers, in type analysers and optimisation passes, where a transformation may only be valid if some property of the code holds; so you have to prove the property correct before you proceed.
In the end, though, I think the most important skill for a software engineer is to be able to choose between tradeoffs. Determining what the possible tradeoffs are is something that only comes with experience. (If I give an experienced software engineer a problem, they should be able to see at least three potential solutions to it.) However, the training comes in when it comes to evaluating the possible solutions. Which has better algorithmic complexity? Which has better constant factors? Which uses less memory? Which has better cache locality? Which has better lock contention? And, once you've answered those questions: Under what circumstances are the previous issues important?
Evaluating possible solutions may in general require all sorts of mathematical skills from the analysis of algorithms, to graph theory, to statistics, to approximation theory, to asymptotics and so on. If there was one skill which isn't currently taught that I'd nominate as vital, it's the ability to estimate (i.e. to perform informed back-of-the-envelope calculations).
Calculus mixed with trig is fundamental to many kinds of numerical simulation problem. Admittedly, you generally solve such problems numerically rather than symbolically, but still.
Nobody has noted this yet, so I guess it's up to me.
Most large systems (and I mean large) provide
some kind of scripting capability, and that scripting system is often dynamically typed. Even if the base system is written in a statically typed language, it will, in general, provide a dynamically typed interface at some level, and some of the system may even be written in that dynamically typed scripting system.
Using this approach, you get the benefits of both. The underlying system, where correctness and performance are important, get written in a statically typed language. The upper levels, where performance is not so critical (because you're effectively just gluing together base components) and flexibility is important, get written in a dynamically typed language.
Reading between the lines on The Pim's reply, and adding my
own gloss, I agree with him. Java is a primitive language.
A "primitive" language is one which relies on one dominant "paradigm" (for lack of a better word). Java (currently) has objects and basically nothing else.
A "non-primitive" language has more than one paradigm available. C++ has objects plus parametric polymorphism (templates), behaviour cancellation (via private inheritance), complex overloading, a source preprocessor and so on. Haskell (which The Pim mentions) has objects (with separation of interface inheritance and implementation inheritance), parametric polymorphism, algebraic data types, first class functions (and hence closures and continuations), and so on.
For large programs, I find this important. By using a multi-paradigm language, I am not locked into one solution space.
You'll see twisted typecasts everywhere, and each typecast is a signal that the type system was in conflict with the needs of the programmer.
That's not my experience. Those typecasts are effectively labels on code that was hard to get correct.
Fixing type problems is not "satisfying the compiler", it's fixing potential errors. Every time you try to break the type system, you're doing something potentially dubious. It should require effort to do that, because it makes you assert that you're doing said potentially dubious thing consciously.
The real issue is that the word "free" is, once again, overloaded far too much.
The GPL is free as in "free speech" (i.e. not enslaved), but the BSD licence is "free" as in "free time" (i.e. no strings attached).
Trying to talk about which licence is "more free" is meaningless because the speakers are using different meanings of the word "free".
(After all if it is then all of Windows legally must be GPL'd..)
For the eighty-thousandth time, this is not true. Just because someone has violated the licence on your code does not give you the right to say what the remedy should be. In particular, it does not automatically give you the right to any of their code.
You could, as a copyright holder, legitimately ask for MS (in this hypothetical case) to remove the infringing code and recall all copies of the software which illegally used your code. Alternatively, you could ask for licence fees. Or you could even reach a settlement with MS which includes them GPLing their code, but you cannot demand this.
You may be able to get away with this if the GPL were some kind of EULA, but it isn't.
Agreed.
If it's "what I do" which is the important factor, then an analogy may help: Someone who builds bridges or office towers is doing civil engineering. Someone who builds cubby houses is not. 7/8 of the world's "coders", as you say, build the software equivalent of cubby houses. I currently work on a 1.5 MLOC C++ project, which is probably the software equivalent of a 30 storey highrise (i.e. not on the scale of the Sears Tower, but fairly complex as these things go).
So even though I don't have an engineering degree proper (mine is CS), I feel like I'm doing engineering. Does that make me an "engineer"? I honestly don't know.
For the record, I have done "coding" for a living, or perhaps "development" at best. I can definitely tell the difference.
Because the US really, really respects the opinion of the rest of the World.
That's true, but threads are just as important on the server. With the exception of serving read-only data (e.g. web servers, DNS servers), server applications rarely fit into the independent-address-space model. As soon as a client can modify state that others may want (and assuming you need multiprocessor scalability, of course) threads are precisely what you need.
You have to remember, though, that threads are there to help solve difficult problems. Such software is hard to develop and debug and test no matter what solution you use.
That's not what the anonymous poster said. They said that C and discipline are not always adequate. C can accomplish anything in the same way that it's possible to use Roman numerals for any number-representation task. That doesn't mean it's an adequate solution. If it costs significantly more to develop the same product for equivalent robustness, performance and functionality in C compared to C++ (or PHP, or whatever), then C is not a more appropriate tool. If it costs prohibitively more, then C is not an adequate tool.
The problem is that there are no good studies which compare the effect of language on development sufficiently to convince everyone, so it's all down to extrapolation and anecdote. There are studies, for example, which show that an average programmer produces so many KLOC per year no matter what the language used, and since 1KLOC of C++ generally does more than 1KLOC of C, C++ is more productive. There are small-scale studies which seem to show that the higher-level the language, the faster you can produce a working product. However, nobody has yet tried getting multiple development teams to develop a medium-to-large scale product in more than one language and see what happens in terms of robustness, efficiency, functionality and development cost.
Speaking from my own experience, I find people using the same arguments against C++ that I used to use... until I actually worked on a large system written in C++. Now I always choose C++ over C unless there is a very compelling reason to do so, like binary compatibility with a legacy system.
Yes. Some have mentioned some reasons for this. I'll mention a one more.
Warning: long rambling post follows.
Like software development, animated filmmaking goes through a "pipeline", which is different for each animation medium. Also like software development, fixing problems earlier in the pipeline is much cheaper than fixing it later. So, for example, fixing an issue on the storyboards is going to be much cheaper than re-animating it.
The specific problem with 3D puppet animation is that fixing problems late in the process is even more expensive than in other kinds of animation.
Take traditional 2D animation, for example. The pipeline looks something like this:
At each stage after storyboarding, the work in progress is "filmed" and, when accepted by the supervisor of whoever is doing it, edited into the film. This is a very important part of the process because it ensures that everything is on the right track. You can usually work out from the key animation "pencil tests" if there are problems in the timing, for example. Then you only need to redo that, then go on to the next phase. If something does need to be fixed, you can often do that by redoing only those drawings that have problems.
The process of testing, redoing and re-testing is inherent in traditional animation. It's very similar with 3D computer animation, too. Everyone has a workstation with OpenGL hardware, so they can watch the action without going through the full render pipeline to see if it works or not. Once they've got it right, they can use that and go onto the next stage.
3D puppet animation is the "hardest" kind of animation from the perspective of testing. Naturally a lot of work goes into pre-visualisation in order to iron out problems early. The animators film themselves going through the pantomime actions in order to work out timing and so on. Computer graphics are used to rehearse camera movements on virtual 3D sets. Once you're done with that, though, it comes down to a physical 3D set with physical lights and physical puppets. If a problem is found here, you can't fix a few drawings and re-paint, or fix a few keyframes and re-render. You may be able to animate some other element and digitally composite it into the final plates, but in general, you have to redo the entire shot.
To complicate things further, in 3D puppet animation, you generally have to shoot the shot from start to finish. Traditional animators (and computer animators) can start with keys in the middle if they want. When you're animating dialogue, you often start with the most emphasised syllable in the line, for example. So you'd better make sure that you start any secondary actions which need to happen early otherwise you need to start all over again.
Of course "it's hard" isn't really an excuse. Good animators should be able to do all this. The trouble is that good animators are hard to find. Film schools don't teach what Aardman has had to find out over the last 20 years by trial and error. Chicken Run only had something like six key animators who were good enough to do the job and as such only had six sets filming concurrently. In feature animation terms, that's a very small amount of concurrency.
Hence it takes a while.
"Release early, release often" is not even close to the same thing as "adopt early, adopt often".
There's a key feature of Id's release scheme that you have to take into account, though. You can't take what Id has released and create a fully functioning Quake. That's because although they have released the source, they have not released the level files which make the game.
That way, they can still sell the game (as part of a bargain anthology or something) if and when they want to.
You never know. It might be more life-like.
Oracle doesn't have "automatic" redundancy, or at least not in the sense you mean. You still need to code your application to handle servers which appear and disappear. While it may be "automatic", it's not "transparent".
For a developer porting applications from Unix to Linux, the number one feature I find missing is true Posix threads. This is happening RSN, I believe. The ability to run C++ destructors on a cancelled thread (Solaris does this, at least) would also be a big help.
There are a few small things which make Linux slightly worse than it otherwise might be, such as proper cache coloring, but this isn't really missing functionality.
Disclaimer: I work in text retrieval for a living.
This is not true.
Recent research has shown it's quicker to access a compressed inverted file than it is to access an uncompressed inverted file, even if the whole index fits in RAM, provided your compression method is fast on your processor.
The reason for this counter-intuitive result is entirely due to cache performance. For a vector search, say, you have to consult the whole index, so your working set is the whole memory. For an inverted file-based search, you only need to consult the terms of interest. Not only is your working set much smaller, it's mostly accessing contiguous blocks of memory in a coherent manner.
I agree. Back to pre-Chaucer English for everyone!
(Someone with more knowledge of Old English than I is probably going to make a terribly funny joke about Beowulf clusters now. I just want to get in first.)
Don't drink and derive?
Didn't you read it? He writes his CGI in C++, so of course he doesn't debug using printf(). Clearly using iostreams is a far superior solution for his application.
The main reasons why studios are switching to Linux is that a) it's sufficiently similar to IRIX that programs port fairly easily (Unix + X11 + OpenGL is pretty portable), and b) you can now get decent hardware (e.g. OpenGL-enabled graphics hardware for previewing) for much less money.
Apart from all the standard Unixy stuff like Linux, bash, Perl, Tcl/Tk, g++ etc, you mean.
So you've never worked in compiler implementation, in deductive databases, in network routing, in operations research and so on?
It's okay that you haven't found a use for these things (yet). You would be well advised not to diss hammers just because you've never seen a nail.
...just about every area of mathematics that a typical CS undergrad learns is going to come in handy some day.
Take, for example, predicate logic. Most of the time, you don't need it. Until, that is, you have complicated business rules to enforce in your program, at which point the best solution is often to encode the rules as axioms and write a theorem prover (or write this part in a logic language, such as Prolog or Mercury, but you still need a grounding in predicate logic in order to use a logic language). Theorem proving also turns up a lot in compilers, in type analysers and optimisation passes, where a transformation may only be valid if some property of the code holds; so you have to prove the property correct before you proceed.
In the end, though, I think the most important skill for a software engineer is to be able to choose between tradeoffs. Determining what the possible tradeoffs are is something that only comes with experience. (If I give an experienced software engineer a problem, they should be able to see at least three potential solutions to it.) However, the training comes in when it comes to evaluating the possible solutions. Which has better algorithmic complexity? Which has better constant factors? Which uses less memory? Which has better cache locality? Which has better lock contention? And, once you've answered those questions: Under what circumstances are the previous issues important?
Evaluating possible solutions may in general require all sorts of mathematical skills from the analysis of algorithms, to graph theory, to statistics, to approximation theory, to asymptotics and so on. If there was one skill which isn't currently taught that I'd nominate as vital, it's the ability to estimate (i.e. to perform informed back-of-the-envelope calculations).
Calculus mixed with trig is fundamental to many kinds of numerical simulation problem. Admittedly, you generally solve such problems numerically rather than symbolically, but still.
I'm a geek, and it had to be explained to me that in the US, they call VW beetles "bugs".
Nobody has noted this yet, so I guess it's up to me.
Most large systems (and I mean large) provide some kind of scripting capability, and that scripting system is often dynamically typed. Even if the base system is written in a statically typed language, it will, in general, provide a dynamically typed interface at some level, and some of the system may even be written in that dynamically typed scripting system.
Using this approach, you get the benefits of both. The underlying system, where correctness and performance are important, get written in a statically typed language. The upper levels, where performance is not so critical (because you're effectively just gluing together base components) and flexibility is important, get written in a dynamically typed language.
Reading between the lines on The Pim's reply, and adding my own gloss, I agree with him. Java is a primitive language.
A "primitive" language is one which relies on one dominant "paradigm" (for lack of a better word). Java (currently) has objects and basically nothing else.
A "non-primitive" language has more than one paradigm available. C++ has objects plus parametric polymorphism (templates), behaviour cancellation (via private inheritance), complex overloading, a source preprocessor and so on. Haskell (which The Pim mentions) has objects (with separation of interface inheritance and implementation inheritance), parametric polymorphism, algebraic data types, first class functions (and hence closures and continuations), and so on.
For large programs, I find this important. By using a multi-paradigm language, I am not locked into one solution space.
That's not my experience. Those typecasts are effectively labels on code that was hard to get correct.
Fixing type problems is not "satisfying the compiler", it's fixing potential errors. Every time you try to break the type system, you're doing something potentially dubious. It should require effort to do that, because it makes you assert that you're doing said potentially dubious thing consciously.
The real issue is that the word "free" is, once again, overloaded far too much. The GPL is free as in "free speech" (i.e. not enslaved), but the BSD licence is "free" as in "free time" (i.e. no strings attached).
Trying to talk about which licence is "more free" is meaningless because the speakers are using different meanings of the word "free".
For the eighty-thousandth time, this is not true. Just because someone has violated the licence on your code does not give you the right to say what the remedy should be. In particular, it does not automatically give you the right to any of their code.
You could, as a copyright holder, legitimately ask for MS (in this hypothetical case) to remove the infringing code and recall all copies of the software which illegally used your code. Alternatively, you could ask for licence fees. Or you could even reach a settlement with MS which includes them GPLing their code, but you cannot demand this.
You may be able to get away with this if the GPL were some kind of EULA, but it isn't.