Home About The Codist RSS Feed

A Tale Of Two Waterfalls
May 05, 2008 20:09 perm link Readers: 1185

Before I poke waterfalls with a stick, a couple of stories.

Story, Waterfall One

Project Manager: What are your requirements?

Customer: I want to float on the Niagara river.

Project Manager: What would you like to float with?

Customer: A boat?

Project Manager: What type of boat do you require?

Customer: Maybe a canoe?

Project Manager: OK, sign here and we will build you a fine canoe!

[Later]

Project Manager: Time for the customer acceptance test, please try it out.

Customer: Hey it works great.

Project Manager: OK, project complete, good luck!

[Customer floats down the river, falls over the edge of the waterfall]

Customer: Wait, this isn't what I need!

Project Manager: Sorry, you agreed to it. Request a change order...

[Customer dies horrible death]

Story, Waterfall Two

Project Manager: What are your requirements?

Customer: I want to float on the Niagara river.

Project Manager: What would you like to float with?

Customer: A boat?

Project Manager: What type of boat do you think you might need?

Customer: Maybe a canoe?

Project Manager: OK, we'll try that out first.

[Team builds a canoe, floats it on the river and it crashes over the falls and breaks]

Project Manager: Hmm, that wasn't the right thing. Maybe an enclosed boat?

Customer: Like a barrel, maybe?

Project Manager: OK, for our next iteration, a barrel.

[Team builds a barrel, puts dummy inside, pushes it over the falls, barrel survives but dummy is cracked]

Project Manager: Hmm, that wasn't quite the right thing. Maybe we pad it heavily?

Customer: OK

[Team builds a padded barrel, puts dummy inside, pushes it over the falls, barrel survives and the dummy is OK]

Customer: That's the thing, I'll take it!

[Customer floats down the river, falls over the edge of the waterfall and survives]

Customer: That's exactly what I needed, thanks!

Discussion

Exaggerated stories aside, the fundamental difference between the venerable (and sadly popular) Waterfall methodology (with its pretty pig-name, SDLC) and the more modern iterative approaches boils down to one main point:

"Customers don't know what they want, much less what they need, until they see it."

In all my almost 27 years in this business, I've learned this over and over again. It's very difficult for customers (i.e. the consumers of your software project) to precisely describe their needs sufficiently to provide an exact list of what they need. Most people have a tough time imagining a software solution sufficiently without a concrete example. Generally they must be guided in an iterative manner to come to a decision point; usually they need to actually get hands on with at least a minimal representation of the software in order to "see" whether it will meet their needs.

The Waterfall/SLDC methodology requires that each step in the process be complete before the following step can reasonably start. You can't start development before all the requirements are known and documented. In theory this should be possible; in practice I've rarely seen it happen except in limited circumstances.

I once knew a guy in the Bay Area who specialized in writing SCSI drivers. He was an expert, and basically did the exact same thing, with minor changes, over and over (plus he made enough to spend 6 months every year in Alaska on vacation, but that's another story!). This type of situation, where everything can be specified up front as there are no real unknowns, makes such a rigid process work. If I write a general ledger for the seventh time in my life, I bet there is little different than the sixth time. If all I am doing is some maintenance on an existing application, I would expect that changes could be documented ahead of time.

If I am writing a brand new system (like I am now at work) there are way too many unknowns to do any kind of up front specification and even design. I don't even know how I will accomplish even the most basic requirements until I have spent some time trying approaches. My "customer" the company is not sure what new products and services that might be possible if the new system can be flexible or scaleable enough. We are replacing an existing system, but it has so many problems and irritations that no one wants to simply replicate it. In this environment all we can do it start with a basic set of needs, build enough to see if the basic architecture works (it has to scale 10x at a minimum of our existing one), then examine how it can be expanded as people see what it can do. There is only one way to work with something unknown and that is iteratively.

This is a hard thing to explain to people for whom waterfall is an embedded part of their psyche. Of course it is also hard to tell people why most of our projects are failing as well. Generally the response to failed waterfall projects is more requirements, more documentation, more analysis. When I was at First Command, we had a 15 step (meetings, documents, signoffs) process before any code was actually written. You would think it would keep projects from happening, and it did (on purpose I always thought).

Story, Sabre Corporate Air Pricing

So how does an iterative, customer involved approach work? As an example, take my experience building a customer facing and internal workflow application for the Sabre Corporate Air Pricing group. Back in 2000, this group (who's job was taking information about flight discounts from travel agencies serving Corporations, and programming them into the Sabre Reservation System). They had about 100 or so people who did the work of "coding". They used faxes and emailed documents from the agencies, and managed the workload by the "drop files on chairs" method. Agencies never knew who long it would take, errors were common and corrections took a long time. Meanwhile errors in discounts were caught by the airlines, and Sabre had to eat the penalties (millions of dollars a year worth). Yet Sabre IT had no interest in helping this group automate; they did write a minimal spec for a web app for the agencies but nothing more. So the group finally had enough and hired the consulting firm I worked for to build the agency facing web app.

Since I was the only person who knew JSP (which Sabre had started using) I worked on that app, completed it per the spec, and then asked a simple question: "OK, now you have data coming from the agencies, what are you going to do with it?". IT had no interest in the question, and the CAP group didn't know anything about web applications at all.

At this point in a normal waterfall you would gather requirements and have them sign off on them. Fortunately I was allowed to do my own thing, and together with another engineer, Dave, we proceeded to learn their business sufficiently to see what was needed. I spent a lot of time explaining what a web application could be made to do, and built numerous HTML prototypes to show them what was possible, and as they began to understand, we jointly decided that they needed the public web app connected to a backend workflow system to manage the workload, and connect the work in progress with status visible to the originating agency, and keep a full audit system also visible to all parties. Over sixth months the two of us (with a bit of help from another) build an application with about 70 jsp pages and a complex Oracle database to back it up.

Then IT finally woke up and decided to get involved (by this time the app was working and in production use by a few customers as a beta). They then spent the next 6 months following their own methodology to add the login page. So we spent the extra time adding many more features and getting more and more beta testers using the system (the agencies loved it).

Sabre basically paid for this system immediately as now they could distinguish internal errors from customer errors and no longer had to pay many penalties at all. In the following two years the system was eventually extended to completely automate the process and (sadly) eliminated the entire department to an enormous savings.

All from a simple question and an iterative and interactive approach to the discovery of what the customer actually needed. Sometimes the only way to find out what a customer needs is to build it over and over again until the app and the needs converge. Agile, scrum or iterative; whatever it's called it's the best way to build something new.

Then no one needs to die pointlessly in a waterfall.

My Tags:

  • Josh: May 06, 2008 08:33

    Very nice!

    Agree with every word in here... in my experience you really need to get your hands dirty with the "customer" and their business process to actually build something that will solve their business need. Odds are, they don't really know what they actually will need.

  • Ryan: May 07, 2008 20:15

    Nice post. I would have to suggest that a project manager's job is to meet requirements (within time, cost, quality). At the completion of the first example, the customer was happy because the requirements were met (before they tried it).

    The second example obviously solves the customer's problem regardless of requirements. Did the project manager charge extra for all these scope changes? How much longer did it take to produce the padded barrel?

    Perhaps a combination approach:

    1/ Build the mock-up canoe and involve the customer. Determine the project scope is incorrect. Modify scope, modify the cost and project time line.

    2/ Build a mock-up barrel and ...

    Coincidentally (with the "water" theme), this is called "rolling wave planning".

    Conclusion: the customer is happy, and the project manager & developers get paid accordingly.

  • Mark: May 07, 2008 21:30

    The project manager then sent the bill to the Customer and the customer did not pay the bill because "that was way too much money for a barrel."

  • Kelly: May 07, 2008 21:59

    I guess your 27 years experience consists of working for clients with limitless budgets, because in the real world that shit isn't going to float.

  • codist: May 08, 2008 05:40

    Actually this works just fine "in the real world" when I've been able to do it. The Sabre project was 2.5 people for about 10 months and saved Sabre millions in penalties. Don't knock it until you've done it.

  • Add Comment

Writing Multithreaded Code Is Like Juggling Chainsaws
Feb 05, 2008 19:24 perm link Readers: 12600

Writing multithreaded code is like juggling chainsaws; amazing when it works and truly sucky when it doesn't.

Right now at my job I am writing the foundation for a transaction processing cluster in Java, so I'm immersed in lots and lots of threads and interacting applications. When you are processing 8000 of something per second, any problems in your approach or in your choice of frameworks is magnified.

In job interviews, a popular question is "what is the major problem you have to solve in writing multithreaded code?" Generally, if they have read a little about it, they often say "avoiding deadlocks". If they have done a bit of thread coding, maybe in Swing, they might say "protected shared data". Only the truly experienced in complex threaded coding will say "avoiding doing nothing".

What's so bad about nothing? Assuming you can avoid deadlocks (generally not hard if you're disciplined) and understand when to protect data, when working in a complex high speed system you want to accomplish both of those basic requirements without slowing down the real work your threads are doing. In a Swing app, so a couple threads block for a while, or even less of a problem is a few waiting around for something to happen. In a large cluster of servers, having threads sitting around doing nothing is a waste of money. If Google is processing millions of searches daily, and half of their cpu's capacity is basically blocked waiting for some resource, it costs a lot of money and power: instead of 50,000 servers you need 100,000. That a hefty price to pay for poor thread coding.

Sure, my company will probably only use 100, and they could afford 200 servers, but why waste resources just to save a few brain cells.

For example, one of my trials used Jetty on one application, and Apache HttpClient on another. With two worker threads on the HttpClient I was able to process my test transactions. When I increased the worker threads to 7, they fell behind; at 10 it was almost dead in the water. WTF? Doing some debugging (with Yourkit Profiler, very nice) the Jetty side was mostly sitting around waiting, but the worker threads in the other app were mostly blocking (as much of 95% of the cpu time). Ah the joys of threaded coding.

The issue turned out to be a synchronized method in HttpClient that deals with Http Parameters, for each parameter for every call on every thread it would pass through this method, creating a common sync point for all the threads. Something that might seem OK for a couple threads was fatal with 10 threads running full tilt at 1000 somethings per second. The chainsaws can be really brutal.

I finally settled on a couple of technologies that work pretty well, on my developer PC (4 core Core Duo something) I was handling 8000 somethings per second at about 85% CPU.

That's another sign of properly avoided nothing, if you slam your creation with unfettered requests and the CPU rises close to 80-95% then you are seeing proper behavior. In my HTTPClient test the CPU rarely got above 25%; mostly a lot of nothing was going on. This was clear with Yourkit. Nothing is not your friend. Don't stop coding when nothing is broken; that's only step one.

Multithreaded coding in a complex application requires a lot of discipline (never assume anything, test everything), experimentation (there is no one way to make it work) and patience (sometimes lots of negative problems lead you to see the solution). It's not easy and it's not quick (never mind the project manager).

Then again neither is juggling chainsaws; plus the downside is pretty nasty.

My Tags:

  • Daniel: Feb 05, 2008 21:39

    "Don't stop coding when nothing is broken; that's only step one."

    That's awesome, I think I'll add that one to my fortune quotes list.

    Ps

    s/What's do bad about/What's so bad about/;

  • AllenJB: Feb 06, 2008 01:45

    Your link & link text are the wrong way round for the YourKit link

  • Tony: Feb 06, 2008 05:36

    On our big, custom data analysis system, we tried to do the whole "framework" and "threads" thing in C++. We wrote about 75K SLOC and it failed utterly due to a host of issues related to timing, overall complexity and lack of design/testing discipline (as you rightly point out). So we threw it all away, went back to the Unix philosophy of "libraries" and "small, single-purpose executables" and "event loops" in C. Wow, what a difference! If you can solve a problem using an "old" technology approach, do yourself a favor and use it.

    I swear I will never work on a project where the words threads, dead-lock, mutex or timing-issues are uttered in meetings again... To butcher a Jamie Zawinski quote: "Some people, when confronted with a problem, think 'I know, I'll use a threaded framework.' Now they have two problems." ;)

    Ha! Love the article.

    Tony

  • Stu Smith: Feb 06, 2008 07:28

    "Writing multithreaded code is like juggling chainsaws; amazing when it works and truly sucky when it doesn't."

    I absolutely agree. What amazes me is that the suggested techniques for dealing with it are exactly the same as they were ten years ago. We seem to have made no practical progress in this area. There are some promising (experimental) techniques for dealing with the problem, but they've been ignored in every modern framework. 'Threading support - stick in a mutex class and let's go to the pub'.

    I'm going to take exception with one paragraph; admittedly I don't know much about your systems, but:

    "That's another sign of properly avoided nothing, if you slam your creation with unfettered requests and the CPU rises close to 80-95% then you are seeing proper behavior. In my HTTPClient test the CPU rarely got above 25%; mostly a lot of nothing was going on."

    Seems wrong to me. Surely anything to do with the network should sit at low CPU levels, it not being a CPU-bounded task? And high CPU levels are not necessarily a sign that all is well. Surely a better metric might be something like "double the number of CPUs, and see a (nearly) 2x improvement in speed"? (Assuming, as I said, it's a CPU-bound operation).

    Incidentally, once experimental technique that caught my eye (software transactional memory) I wrote up into actual working code... if you're interested:

    http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17791

    Stu

  • a: Feb 06, 2008 08:05

    Uhhh, okay, so the synchronized block created a constrained resource.

    That all the other threads were blocked from using, since one thread was probably hogging it.

    While not permanent deadlock, that is basically deadlock, not doing nothing. It's a constrained resource that one thread was holding to the exclusion of the others.

    An interesting story though, I wonder why the parameter processing was synchronized. Pretty crappy design if you ask me...

  • Ed: Feb 06, 2008 08:13

    "Seems wrong to me. Surely anything to do with the network should sit at low CPU levels, it not being a CPU-bounded task?"

    It depends on how big your requests are. If your hitting the server with alot of small requests (<1kb lets say) then it probably be more CPU bound then network bound. Using 1Kb requests size as an example, if the server is processing 8000 requests a second, then that's only 8 MB/s transfer, which isn't a considerable amount of bandwidth. And for the server I'm wrote and am current maintaining for works requests are actually smaller then 100 bytes, an order of magnitude smaller.

  • Michael Davis: Feb 06, 2008 08:21

    "Seems wrong to me. Surely anything to do with the network should sit at low CPU levels..."

    I guess it depends on what the application is doing. If it's doing serious encryption or advanced mathematical transformations, it may well be CPU-bound. If it's doing database searching, it will likely be IO-bound.

  • Stephane Grenier: Feb 06, 2008 08:24

    I love your opening line: "Writing multithreaded code is like juggling chainsaws; amazing when it works and truly sucky when it doesn't." It's perfect!

    I remember writing an application a while back where we were trying to surf the net, just the first page of every website, parse it, and store some resulting calculations in a database for research purposes. Avoiding blocking was pretty simple. Even avoiding data issues wasn't too hard. The really hard part, as you stated, was unused processing time. How do you max out each thread to it's max potential. Not CPU processing, but effectiveness. This took quite some time.

    For example for us, sometimes a thread would have to wait for a website to return. Not all servers have good response times. This is dead time for a thread. We could increase the thread count, but then there's more process swapping. Figuring this out, and maximizing the effectiveness took a good deal of effort. And it wasn't until we got into these optimizations that we started to face harder deadlocking/data issues. Before we optimized our world was much simpler. Optimizing to avoid deadtime significantly increased our threads.

    The good news is that we went from surfing 100k sites to 4 million on the same hardware. A very significant gain!

    Great article!

  • Domagoj Klepac: Feb 06, 2008 08:39

    So how did you solve your HTTPClient params problem? Because I have the same problem, and have to set HTTP params for each request. :)

  • codist: Feb 06, 2008 09:11

    I wound up using Apache Mina and a custom protocol over plain sockets instead of HTTP. THere is probably some way with HTTPClient to avoid sharing the parameter issue (I didn't go further with it, but I am sure you can have a separate state for each Thread).

  • Domagoj Klepac: Feb 06, 2008 09:59

    Wow, didn't know about Apache Mina, looks interesting. Thanks for response, seems that I'll have to dig into HTTPClient...

  • Aminorex: Feb 06, 2008 11:14

    One has to ask why you keep juggling chainsaws. It seems a remarkably unclever thing to do. I have to guess that you are not getting the kind of risk-reward that the Brothers Karamazov got during their extended stints in Vegas. It's lovely to know that you've learned to do it well enough so as to minimize finger reattachment surgeries, but even so...

  • jc: Feb 06, 2008 11:15

    I can truly sympathize with you. I gained much (experience) and lost some (hair) in writing threaded code. Its akin to being a babysitter with infinite babies to "sit". It was also fun.

  • JC: Feb 06, 2008 14:58

    I feel your pain (and joy)! I wrote a replacement for Java RMI with: resizable thread pools (while the system is processing requests!), controlled timeouts, separate thread allotments based on the type of workload, O(1) thread allocation/deallocation, pluggable transports, asynchronous calls, controlled degradation (server busy messages anyone?) and denial-of-service protection.

    It was one of the most painful and gratifying projects I've ever worked with. I still think of it as one of the pieces of work that make me proudest (is that even a word?).

    I really enjoyed your article, keep'em coming!

  • Imp: Feb 07, 2008 13:01

    I agree that it's bad if the threads spend too much time blocked. It's an indication that your locks aren't granular enough (e.g. you should look at locking a row rather than the entire table). However, just having the CPU rise with load is not indication that you've gotten it right either. In general more granularity means more concurrent threads, but if your locks are too granular then you can waste a lot of cycles locking and unlocking unnecessarily (e.g. you should consider locking a page rather than an single row).

    One good indication that you've gotten the granularity right is how much contention there is for locks. If an average lock takes 1ms to get, and is held for 100ms then if you don't have contention for 1% of locks then you can probably get better performance by having less granularity in your locks (even though it might mean that the CPU isn't pegged).

  • Steve Campbell: Feb 08, 2008 11:15

    There are some API patterns that can insulate from many of the complexities, at the expense of using thread-pools. Working with individual threads is painful in comparison. Kindof like programming in Assembly vs C, or C vs Java (similar performance arguments apply).

    Some examples... the BackgroundWorker component in .NET. Or even the basic .StartSomething + .EndSomething (callback) pattern common in many .NET libraries. (Sorry, I do not know Java examples).

  • Add Comment

If Java Is A Dinosaur, Then I Must Be In The Triassic Era
Jan 08, 2008 19:12 perm link Readers: 1835

I keep reading blog posts where people equate Java with Cobol, that it's a dying language not suited for work today, and that people who use Java are generally less intelligent about programming in general. Given that dinosaurs ruled the earth another 50 million years or so after the Triassic period, I'd say Java still has a long useful lifespan.

Not that it's perfect at all, but I've been using Java for almost 10 years now, and compared to my years of C and C++ I am fairly glad I moved on. I've worked for years starting with Basic, then Fortran, Pascal, Assembly, C, C++, Objective-C and finally to Java; I've seen a steady improvement in my ability to be productive with my language and its entourage (frameworks, libraries and communities). Like the dinosaur, every language eventually falls out of favor as new "mammals" appear but rarely does a language die out completely. Like most animals and plants, they survive and even thrive in different environments way beyond the general evolutionary landscape that might otherwise kill them off. How else can you explain Object Cobol?

For me I find I can do almost anything in Java, provided a reasonable set of choices for the environment I am writing code in. I dislike most of J2EE but there are so many better ways that have sprung up to write Java applications unless you are forced to use the worst of breed "standards". It's not the language that kills so much as the accompanying baggage you have to drag around with you. Java may not be a perfect language design (if such as thing can even be agreed on) but it gets my job done.

Not that I intend to sit on my butt and become dinosaur fodder. Scala, Erlang and Haskell are languages I find fascinating to study, although Scala being JVM based makes it more likely to be useful to me. I think of Groovy as a more laid-back Java, and relatively easy to pick up as well for us Triassic Java coders.

Give me any decent language, and I can write any decent program. The difference is always in how long will it take, how reliable will it be, and how well can it be maintained. That is the mark of a good programmer no matter what they use to write with. Of course the choice of language does make a difference, but choosing the right tools for the job is also a mark of a good programmer. Often you have no choice (other than seek alternative employment or become an advocate for change) and you have to work with what you have. There is real skill in writing good code, and real skill in understanding the strengths and weaknesses of your chosen (or forced upon) toolset.

Often a language which requires a great deal of experience and understanding to master leads the average programmer to fail miserably. I'm sorry, writing complex C++ programs is not for a beginner. Even Java can be difficult (such as at my newest job where a whole set of mainframe programmers face the difficulty of learning a new language or having to leave) if you are not familiar with the concepts of OO programming. Is there a market for people who need a simpler language? Of course there is; but never assume mastery of a simple language or toolset means automatically that you can move on to more complex projects, or even assume your basic language choice can itself handle tougher problems. The world is littered with way too many VB/Access apps on an enterprise scale, for example.

So is there something wrong with learning Java, or using Java, or even improving Java? No there isn't, unless you take the approach that you will stop using Java when they pry it from your cold dead hands. It isn't the final stop on the programming roadway but it's a powerful, useful language with an enormous open source community, great tools, and works for a variety of uses.

Face it, there isn't any one solution to writing code, any more than there was when I started in 1981 writing Fortran. No matter what your favorite new language is, someday it will suck and people will laugh at you. So the trick is to work with the best choices available to you, and keep your eyes open for the new mammals on the block.

If I'm still coding in 50 million years I'll probably not be using Java.

My Tags:

  • Petrus: Jan 11, 2008 00:23

    It is really important to choose the best tool for the job (as you have stated) and it also important to remember that Java is just a language. I think that the future of Java lies in it's ability to adapt and evolve, and with evolve I mean change. There is no use just adding new features. I see that in the future we will also be using more of a 'slang' than a specific language by combining different languages and their associated strong points.

  • evanx: Jan 14, 2008 03:43

    you cannot choose the best tool for the job in isolation. Usually you don't get to rebel and use whatever new sexy language you want to adopt as your experient of the month. Because you must be dispensible, and other programmers will maintain your previous, once you've moved on, passed on, or are on leave. So it's the best tool for the company, where all key software is written in the same language, so everyone's banging on the same drum.

  • Add Comment

Ask Me How Much I Hate XCode and C
Dec 12, 2007 19:49 perm link Readers: 1884

In the mid-90's I spent 5 years working exclusively in C++ after years of C. I learned all the ins and out of STL, templates, overloading and the like. Now after 10 years of Java I've spent a little time working with C++ again - working on some game code for WWIIOnline, rewriting my sound code again to support Core Audio in Leopard (and eliminating OpenAL use).

Argh, C++ is so painful to me now, and XCode as an IDE is beyond lame compared to my beloved IntelliJ and even the recently learned Eclipse. Poke me in the eye with a C# stick, it would hurt less.

XCode is the latest generation from Apple, going back to the early days of MPW in the 80's, and then passing through the tools from NEXT. Some days I really feel that the folks at Apple have never worked with a real Java IDE. Other days I feel sorry for them having to carry the baggage of a generation of make files and command line tools around all day. I mean IntelliJ and Eclipse are constantly compiling the Java source while I am typing it in, making it easy for the IDE to spot errors, inconsistencies, provide tips and hints and refactorings on the fly. C++ (and even Objective-C) despite on paper being faster in execution, apparently cannot be compiled fast enough to provide the same level of feedback. With IntelliJ I rarely ever see a compiler error. With Eclipse I rarely even see the compiler at all.

So working in C++ and XCode is really painful for a Java guy like me. Yeah if I was working in Cocoa and Objective-C, it might be more pleasant, but that's not the option here. Even then, in XCode I miss all the help I get from the IDE's that I'm used to. I know people love vi and emacs and swear by command lines but I don't miss the command line these days anymore than I miss the IBM PC XT.

Of course C++ all by itself is a painful language anyway. Sure, I can create the most complicated meta-templated code I'll never understand 5 minutes later but how is that productive? I remember when I first started working on this it took me ages to remember all the requirements for storing objects in a map. Maybe my brain has been too comfortable in Java where putting an object in a HashMap is just that. Maybe the occasional overriding of hashCode() and equals() but nothing much to remember.

Don't get me thinking about memory management. In Java I don't. In C++ you always have to remember when to get rid of stuff. At least in the latest Objective-C they finally added automatic garbage collection. This is the 21st century after all. As Homer Simpson once sang in an episode where he becomes the garbage commissioner "let someone else do it".

I wrote a commercial C++ memory manager in the 90's so I'm well aware of what it takes, and even wrote the whole thing in heavily templated C++, but that was a century ago it seems. Today I'd rather work on the problem at hand instead of futzing with a language and tools that get in the way. Of course for some folks even Java gets in the way (and I understand that as well but it's not a choice for my job yet) but at least it's not C++.

When I read about the newer features being added to C++ I can only think of all the profits the Tylenol folks are going to get. Effective use of C++'s features requires a real dedication to understanding their strengths and weaknesses. It's not a language for occasional use. When I used it everyday it was painful but familiar; today having worked with Java I have a hard time keeping C++ features in my head.

The bottom line for me is I want the computer to do all the heavy lifting, and let me focus on the actual work to be done with as little annoyance and loss of focus as possible. No matter what language or tools you choose they better meet that requirement (for you) or try something else.

Or break out the pain killers.

My Tags:

  • codist: Dec 12, 2007 19:51

    My blog code ate the C++ in the title. Must be a Java problem :-)

  • teqman: Dec 13, 2007 02:28

    You are aware that Apple is writing a new compiler (llvm-clang) so that it can support many of the very features you're complaining about?

  • Anonymoose: Dec 13, 2007 02:45

    > In C++ you always have to remember when to get rid of stuff.

    C++ has a better resource management setup than Java or Objective-C. It's called a destructor. As soon as your object leaves scope, it's cleaned up, instantly. Sure, sometimes objects have more dynamic lifetimes, but that's what smart pointers are for.

    As a Java programmer, I'm sure you're familiar with the pain of writing a correct try/catch/finally (it's not hard, it's just -annoying-) sequence to make sure all of your files, sockets, etc. are all closed. Isn't it a bit crazy that .close() can throw exceptions? C++ fstreams are closed automatically, whether by exception or early return, hook or by crook.

    Agreed on all other points, though.

  • Stephane Grenier: Dec 13, 2007 08:57

    That's exactly the reason why I can't go back to my old C++ days.

    Above this, languages like Java have also removed things that can greatly reduce productivity like operator overloading. Sure it helps the original author write faster, but every person afterwards can be negatively affected. It's hard to read code where every other file the operators can mean something else. And the reality is that over the code's lifecycle, a lot more time is spent trying read and understand it than writing it.

    But you're absolutely right. The IDE's are great. The language does a lot of things for you that you now take for granted. I can't go back :)

  • Miro: Dec 14, 2007 18:16

    To Anonymoose:

    Objective-C does have destructor too. Read the manual.

  • bobert: Dec 15, 2007 22:09

    I've stuck primarily with C/C++ since the Jurassic when Andrew and Ken I were carving Trapeze into the Mac silicon while fending off velociraptors. We happily used Lightspeed C (later Think C), which was fast because Michael Kahl's idea was that programmers work best when the compile/link/test cycle is as rapid as possible.

    When Symantec ate Think and turned it into mush, and Michael jumped ship to Metrowerks, I then switched to CodeWarrior, and used it cheerfully to write C/C++ for MacOS and Windows. In addition to an incredibly fast compile/link cycle, it had a very simple user interface. You had a small project window, and as many source file windows open as you wanted. The configuration for a project was very simple, too. The 20% of the settings you needed to fiddle with 80% of the time were easy to get to, and the rest weren't too hard, either. And the source-level debugger was simple but brilliant. In fact, on Windows, I would often write a UI in Visual Studio/MFC, and put all the non-UI functionality into DLLs that I built with CodeWarrior.

    But now CodeWarrior is no more for either platform. Nowadays, I mostly use GCC on Linux, XCode/GCC on MacOS, and Visual Studio on Windows. And my productivity has dropped through the floor. Why?

    1. Slow, slow, slow. Inexcusably slow. CodeWarrior is at least an order of magnitude faster than Visual Studio, and maybe two orders faster than GCC, at compiling and linking the same files on the same hardware. So instead of zoning out for a few seconds after editing code while I wait to see the effects, it's often minutes, which leads me to do something else (like read a blog), and then I'm toast. (Apple's answer to CodeWarrior junkies is: buy a lot of Macs and network them into a private build farm. Yah.)

    2. Complicated. Take a look at the complete list of build settings for a target in XCode or Visual Studio. What the heck are all these things? And my experience with XCode has been that for any project beyond trivial (e.g. something that uses shared objects or frameworks you build yourself), you really have to know what they all are and have all of them set right or they'll bite you hard. Ditto with Visual Studio when it comes to things like which version of the standard C library to link with (multithreaded/single-threaded, DLL vs. static, yadda yadda).

    3. Inflexible, especially GCC. Say you have a piece of code that would normally generate a warning, but you know it's ok. In Visual Studio, and in CodeWarrior, you could turn an individual warning off for a section of code in a file, then turn it back on. Not in GCC/XCode. (And don't get me started on _why_ GCC doesn't have fine-grained warning control.)

    I still love what I can do with C/C++. There are days when I work on C/C++ code all the way from end-user apps, through middleware like modding the open-source GTK package, into farily low-level stuff like hacking my X server's attachment to the hardware frame buffer, and even dig around in the Linux kernel. But it sure would be a lot more fun if the tools didn't suck so much.

  • IT: Dec 25, 2007 01:31

    Actually, Homer said "Can't someone else do it?"

  • Add Comment

Apple Is Now Worth More Than IBM!
Oct 22, 2007 20:42 perm link Readers: 1042

Amazing, Apple's stock value just exceeded IBM's for the first time in history.

I would have never thought this possible back in 1984.

My Tags:

  • Thomas Mueller: Oct 23, 2007 00:05

    In my view, this is just another sign that something is wrong with the market. Other signs are the Google stock value, and there are too many startup companies. I guess things will look different in one year.

  • Stephen Uitti: Nov 05, 2007 14:33

    In the mid to late 70's my brothers went to a computer convention. They pretty much ignored the two loosers at one booth, Paul and Bill.

    By 1984, Apple had been shipping products for a bit. Bigger than IBM? I dunno. IBM had a pretty odd machine at the PC end. It looked easy to beat. In 1987, though, i bought a clone, even though i really wanted a real machine, so I also bought a Mac II. If you'd asked me six months earlier, i'd have said i'd get an Amiga. So, i can't even predict myself. I'd like to think i know something about myself.

    In 2001, i replaced my aging Mac with a Linux box. Hey, it could do word processing!

    Try this out. Now that Apple's OS/X runs on x86, and people have gotten it to run on non-Apple hardware, what do you think the odds are that Apple will sell it to people who want to run it on their own stuff (for whatever reason)?

  • Nic Strong: Nov 14, 2007 07:03

    But apple sucks. Ballance restored.

  • enkriptid: Jan 19, 2008 22:21

    good one Nic Strong..

  • Add Comment

Name:


Optional URL:


Comment:


Save Cancel

Copyright © 2007 By Andrew Wulf