Intuitive Bug-less Software?
Starlover writes "In the latest java.sun.com feature at Sun's Java site, Victoria Livschitz takes on some ideas of Jaron Lanier on how to make software less buggy. She makes a couple of interesting points. First, making software more 'intuitive' for developers will reduce bugs. Second, software should more closely simulate the real world, so we should be expanding the pure object-oriented paradigm to allow for a richer set of basic abstractions -- like processes and conditions. The simple division of structures into hierarchies and collections in software too simple for our needs according to Livschitz. She offers a set of ideas explaining how to get 'there' from here. Comments?"
She misuses the term functional programming. I'm assuming she meant imperative languages. A lot of the problems could be solved with true functional languages (Haskell, OCaml, etc) but the learning curve is too high. Especially when you can get a team of second rate VB coders for the price of one haskell coder (if you can find one) But really, do you want working code now? Or perfect code in 10 years? That's where the problem is. Time.
The first is the intense pressure to get the product to market. This is especially true for custom code, written specifically for one client. They want it fast and cheap and in order to satisfy this desire, code invariably gets released/installed before it's ready. Then the "month of hell" starts as the client starts complaining about bugs, "bugs" and other problems and we bend over backwards to get it right.
As a ISV, we have no choice but to do it this way. If we don't quote the project with this in mind, the client will hire somebody else with a better "can-do attitude".
The second big reason software is buggy is because all the underlying tools (e.g. code bases, code objects, .dlls, etc.) are buggy as hell. I spend more time working around inherent bugs than I do debugging my own code.
Most programmers are perfectly capable of making their own code solid, given enough time.
I've made up my mind and now I've got to lie in it.
To produce bugless software we need to start with software designs that are provably correct and then produce code that is provably in line with the design. Using more objects that more closely model the "real world" is an invitation to producing larger number of bugs as the ambiguity of the real world infects the design and implementation of the program.
avoiding the obvious while promising the impossible
this is an exercise in wish-fulfillment, in suspending disbelief
writing software with less bugs by making things more intuitive and less hierarchical?
i mean, that's funny!
we're talking about telling machines what to do, that is what software writing is
writing software is an extremely hierarchical exercise, the art is giving people want they want
intellectual property law is philosophically incoherent. it is your moral duty to ignore it or sabotage it
I think the current tools exist to produce code that is way less buggy. For instance much of the industrial code I have seen written in Java poorly uses the OO capabilities of Java, and this in itself causes more bugs and maintainability problems. It seems fairly rare that the existent OO languages and tools are well used at least at the application developer level. So I think the problem is really more with the abililty of developers to use proper and well implemented OO methodology. It also seems as though the design process is flawed in that class designs etc., are often done with a priori with insufficient in depth understanding of the process that is being modelled, this is usually because management insist upon having an immutable design before development starts and often before the problem and proceeses the code is being written for is sufficiently understood. Bottom line is you can hand anyone a scapel, but it doesn't make them a surgeon. Skilled developers with a good understanding of the underlying process they are coding for will produce better qualilty and maintainable code. Because it is developer skill that is the issue, not tools the current race-to-the bottom to off shore all devepment to the lowest bidder and lowest developer skill will inherently produce less maintainable, buggier code. The solution to less buggy code is to use skilled programmers wha really understand and can use the available OO techniques (ie NOT offshore, NOT H1-B etc.). I think it also helps if the developers have some understanding of the field for which they code ie medical, financial etc. When you go with the lowest bidder, you get what you pay for /rant)
MM
I ask because I'm currently looking into dependent type systems, which aren't currently practical. However, their claim to fame is that the type system is much more expressive; it is possible to define types like "date" or "mp3" in them, and ensure that wrong data cannot be supplied to functions. As I play though, I get the feeling that if the type system is too powerful, people will just create bugs in types, and we'll not improve by as much as we could do.
I appear to have a blog. Odd.
Dijkstra has a few things to say on the topic as well:
On Education, Specifically:
And then on Computer Science in general:
Thanks,
--
Matt
Why is it so difficult, if not impossible, to write bug-free programs that contain more than 20 to 30 million lines of code?
Maybe because the programs contain 20 to 30 million lines of code.
Look, I understand that a lot of people are yearning for the good old days when software was less buggy. You know what? I suppose that if your entire application consists of something like 4000 assembly code instructions, you might just be able to make the program bug-free.
But it's not 1983 anymore and programs are on the order of millions of lines of code. Of course it's not feasible to go over the entire program manually and root out every single bug. The stuff I work with every day is considered extremely small and yet it depends on all sorts of external libraries, each of which may have dependencies, etc. It all adds up to amazingly large amounts of code. But, it requires large amounts of code to do extremely complicated things. Is this a surprise to her or something? I don't think there's any "paradigm shift" in the field of programming that's going to change the fact that:
* Doing complicated things requires lots of code.
* The more code you write, the higher the chance of bugs.
I reiterate: duh...
Perl's OO model isn't.
That's not to say it's bad, but it simply isn't. Perl provides you with all of the tools you need to build a GREAT OO system, but that's not an OO system.
This is one of those things that Larry does that's just unfathomable to the rest of the world. He didn't really grok OO back 10 years ago when P5 was in the works. He understood it well enough to program in the large in C++, but he didn't quite have his head fully around the implications, so when he added OO to Perl 5, he did so in such a way that all of the various ways of approaching code from an OO standpoint could be accomodated.
This means that writing OO code in Perl kind of sucks, but if you want to design an OO model for a programming language, no tool (other than a parser generator) will be more powerful.
Come Perl 6, Larry finally feels that he gets it enough to tell all of the people who are going to have to use his language how to do it. He doesn't take that responsibility lightly, and the fact that SO MANY other language designers do should worry you.
That said, if you want to write medium-sized programs that are heavily OO-dependent, I suggest Ruby or Python or even Java. If you are writing small tools, OO vs non-OO won't matter that much.
If you are building huge systems, then you don't care because the amount of work required to lay out how you will use OO in Perl is insignificant next to the architecture that you have to lay out for the rest of your app. It's just noise in your timeline, and you can fully re-use that policy in every other project that your company tackles.
What's amazing is how Perl lets all of these OO models interact. I'm always stunned by this, and frankly it's a tribute to the language and its designer.
As for your comment about typing less... I don't think that languages with the level of abstraction of Ruby or Perl really need to have line-count contests. Dynamic typing, run-time data structure definition and garbage collection make programming SO much easier that Perl and Ruby are in the same order of magnitude, and I don't see a reason to quibble over the details.
> This is the old way of thinking. When you see the answer, I'm sure you'll jump on board.
I did a PhD at Oxford in the Programming Research Group and studied Z, CSP and all that stuff. My thesis even includes a program written in Occam proven via an algebra to meet a security specification.
Believe me, I'm aware of what the world could be like, but it is not practical to write real software this way yet. Hence we still need to test, and not enough people write tests today. Unit and system testing are best practices for the industry today, sure, there's a better theoretical way to do things, but I need to code in 2004 not 2054.
John.
I couldn't stop thinking of existing theories and/or implementations of her ideas...
Modeling processes out of the OO paradigm (opposite to what Design patterns started to sacralize for example) is precisly the subjet of so-called business rules. But BR people are close to relationnal model of data, that is too quickly assimilated with SQL DBMS(*), so OO oriented people don't buy it (see the almighty impedance mismatch).
Data-structures other than trees and collections are already genericaly implementable in any modern OO language. See Eiffel for example which can perfectly do that for 15 years (parametric classes, with full type safety). May be the java generics will help to build highly reusable data structure... I doubt that, anchored type is missing (ie the possibility to declare the type of a variable as equal to another type, nearly mandatory when dealing with inheritance of generics).
Tom.
(*) I warmly recommend the writings of Chris Date and Fabian Pascal to really see how the relationnal model of data is different from SQL databases...see DBDebunk for references.
The article doesn't seem to address all of the different types of bugs, nor how to best address them. Anyone care to add to or refine this list?
1. Algorithmic bugs - you have a function with well-defined input and output, and it does the wrong thing (may include giving the wrong answer, looping forever, leaking memory, or taking too long to return). Can be avoided with a combination of code review, unit tests, and correctness proofs when possible.
2. Interface bugs - this includes validating input, both from the user and over the network or other ways in which your program gets input data. These bugs include buffer overruns, GUI bugs caused by an unanticipated sequence of clicks, etc. These bugs are mostly found by testing, but sometimes also with automatic code checkers or memory debuggers that highlight potential problems.
3. Bugs in the operating system or in sublibraries - any large project depends on large volumes of operating system code and usually lots of other libraries. These systems almost certainly have bugs or at the very least undocumented or inconsistent behavior. The only way to avoid this is to validate all OS responses and do lots of testing.
4. Cross-platform bugs - a program could work perfectly on one system, but not on another. Best way to address this is to abstract all of the parts of your program that are specific to the environment, but mostly this just requires lots of testing and porting.
5. Complexity bugs - bugs that start to appear when a program or part of a program gets too complicated, such that changing any one piece causes so many unintended side-effects that it becomes impossible to keep track of them. This is one of the few areas where good object-oriented design will probably help.
6. Poor specifications - these are not even necessarily bugs, just cases where a program doesn't behave as expected because the specifications were wrong or ambiguous. The way to avoid this is to make sure that the specifications are always clear. Resolve any potential ambiguities in the specs before finishing the code.
My overall feeling is that there are so many different types of bugs in a real-world programming project, and any one technique (like object-oriented design) only helps address one type of bug.