Here are a few things I have learned about programming computers, in no particular order. I didn’t invent any of them, and I don’t always follow them. But since nobody seems to know very much about making good software, it makes sense to try to distill a little wisdom when possible.
Fail Fast
Check for programming errors early and often, and report them in a suitably dramatic way. Errors get more expensive to fix as the development process progresses–an error that the programmer catches in her own testing is far cheaper then one the QA tester finds, which is in turn far cheaper than the one your largest customer calls to complain about. The reason this matters is that the cost of software comes almost entirely from the errors. To understand why this is, consider writing code in the following manner: you are assigned some feature, you type up a complete implementation all in one go, then you hit compile for the first time. (I TA’d a beginning programming class in grad school and this is not very different from how beginning programmers insist on working.) The point is that if you have any experience writing software you know that if getting to the first compile required n man-hours, then the time required to having shippable code is probably between 2n and 100n man-hours, depending on the domain. That time will be divided between the programmer’s own bootstrap testing, QA time (and the associated bug fixing), and perhaps some kind of beta.
The classic examples of this principle are type-checking, unit testing, and the assert statement. When I first learned about the assert statement I couldn’t accept that it was useful–after all, the worst thing that can happen is that your code can crash, right? and that is what the assert statement causes. For all the hoopla about unit testing, you would think that it was something deeper then just a convention for where to put your assert statements. But software development is in such an infantile stage, that we shouldn’t poke fun–unit testing, for all the child-like glee of its proponents–may well be the software engineering innovation of the decade.
You see the violation of the fail fast principle all the time in Java programming where beginning programmers will catch (and perhaps log) exceptions and return some totally made up value like -1 or null to indicate failure. They think they are preventing failures (after all whenever an exception shows up in the logs it is a problem, right?) when really they are removing simple failures and inserting subtle time-sucking bugs.
Unfortunately the idea of failing fast is counter-intuitive. People hate the immediate cause of pain not the underlying cause. Maybe this is why you hear so many people say they hate dentists, and so few say they hate, I don’t know, plaque. This is a lot of what irritates people about statically typed languages–when the compiler complains we hate the compiler, when the program does what we say and crashes we hate ourselves for screwing up–even when it is an error that could have been discovered by a more vigilant compiler.
This is why I can’t work myself into the same first-kiss level of ecstasy others manage over languages like Ruby[1]. Dynamic code feels great to program in. After the first day you have half the system built. I did a huge portion of my thesis work in Python and it was a life saver. Thesis work doesn’t need to be bug free, it is the quintessential proof-of-concept (and yet so many CS students, when faced with a problem, break out the C++). But I have also worked on a large, multi-programmer, multi-year project, and this was not so pleasent. A large dynamically typed code base exhibits all the problems you would expect: interfaces are poorly documented and ever changing, uncommon code paths produce errors that would be caught by type checking, and IDE support is weak. The saving grace is that one person can do so much more in Python or Ruby that maybe you can turn your 10 programmer program into three one programmer programs and win out big, but this isn’t possible in a lot of domains. It is odd that evangelists for dynamic languages (many of whom have never worked on a large, dynamically-typed project) seem to want to deny that static type-checking finds errors, rather than just saying that type-checking isn’t worth the trouble when you are writing code trapped between a dynamically typed database interface and a string-only web interface.
Syntax highlighting (and auto-compilation) in IDEs is another example of this principle, but on a much shorter timescale. Once you have become accustomed to having your errors revealed instantaneously it is painful to switch back to having to wait for a compiler to print them out in bulk one at a time.
Write Less Code (and Don’t Repeat Yourself)
This is perhaps the most important and deep principle in software engineering, and many lesser principles can be derived from it. Somehow simple statements/programs/explanations/models are more likely to be correct. No one knows why this is; perhaps it is some deep fact about the universe, but it seems to be true.
In software this comes into play as bugs: longer programs have a lot more bugs so longer programs cost more.
Worse, difficulty seems to scale super-linearly as a function of lines of code. In the transition from Windows XP to Vista the codebase went from 40 million to 50 million lines of code. To do this took 2,000 of the world’s best software engineers 5 years of work.
The reason for this is that the only way to get real decreases in program size (decreases of more than a few characters or lines) is to exploit symmetry in the problem you are solving. Inheritance is a way to exploit symmetry by creating type hierarchies, design patterns are an attempt to exploit symmetry of solution type. Functional languages are still the king of symmetry (all of lisp is built out of a few primitive functions). But rather than categorize these by the mechanism of the solution, it is better to think of them as what they are: ways to write less code.
The best way of all to avoid writing code is to use high quality libraries. The next time you find yourself writing a web application reflect on how little of the code executing is really yours, and how much belongs to the Linux kernel, Internet Explorer, the Windows XP, Oracle, Java, and the vast arrays of libraries you rely on (”ahh the old hibernate/spring/JSF/MySQL solution, so lightweight…”).
Some of the difficulties of large programs are technical but many are sociopolitical. Microsoft is the size of a medium sized country by income and the size of at least a small city by head-count. Yet it is run in much the same way as any 200 person company, namely some guy tells some other guy what to do, and he tells you. Unfortunately they have found that none of these things work at that scale, and I don’t think anyone has a really good idea of how to fix them.
Your problem doesn’t require a small city to produce, but the principle is the same. If your solution requires double the man-power then all the organizational overhead will have to be developed to handle this. Furthermore the organization will be composed of computer programmers who are often at roughly the same level of interpersonal sophistication as that sling blade guy.
What is remarkable, though, is that to make the solution small means also making it clear. I think that this has mostly to do with human brains. We can only think one or maybe two sentences worth of thought at a time, so finding the concepts that make your solution one sentence is essential. The famous haskell quicksort is a perfect example of this. I can’t help but feel jealous of the computer science students ten years from now who will see algorithms presented in that way. (If you don’t read haskell the program just says: “An empty list is quicksorted. The quicksort of a non-empty list is the concatenation of (1) the quicksort of list elements less than the first element, (2) the first element itself, and (3) and the quicksort of list elements greater than the first element.” Though, of course, the haskell version is much briefer.)
Computer Programs Are For People
“We want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.”
The Structure and Interpretation of Computer Programs
The wonderful thing about the above quote is that it gets less brave and more obvious every year. We know that c/java/lisp/haskell have not one bit of power that isn’t in simple assembly langauge–they only allow us to express the ideas more clearly and prevent certain kinds of stupid mistakes. There is no program that can be written in one that can’t be written in another, and all end up as machine instructions sooner or later (some at compile time, some at run time, but no matter). Given this fact it should be obvious that the only reason to have a programming language is to communicate to a person. Don Knuth wrote about this idea, calling it Literate Programming, and created a system called WEB which was a great idea mired in a terrible implementation[2]. The idea was to embed the program in an essay about the program that explained how it worked. The Sun programmers simplified this in some ways with Javadoc, but still something was lost, since it is very hard to get any of the big ideas out of Javadoc, or even to know where to start reading. Projects always have two links: one for Javadoc and one for a higher level documentation which is written in some other system. WEB created a linear narrative to describe a program that might not be quite so straight-forward; Javadoc creates a flat list of documentation with no beginning, end, or summary. Neither is quite what I want.
It is a small tragedy that programmers who spend so much time trying to understand obscure code, and so much time creating new lanauges to write more obscure code in, spend so little time coming up with the WYSIWYG version of WEB that makes program source input look like the beautiful WEB/TEX output.
I think the best ideas in object-oriented programming also fall under this category. The methodology of solving a problem by creating a domain model to express your problem in is the best example. The point of such a model is to create that level of abstraction which exists wholly for people to think in. Not all problems are easily broken by such a method but many are. The concept of encapsulation (you know, the reason you type private in front of all those java variables) is another example. Both of these are to make things simpler, more usable, to put it simply, more human.
A sort of corollary of writing computer programs for people, writing less code, and solving the general problem is the following: write short functions. If I could transmit only a single sentence to the programmers of tomorrow which summed up everything I knew it would be that: write short functions[3]. When you write short functions you are forced to break the code into logical divisions and you create a natural vocabulary built out of function names. This makes the code an easily readable, easily testable, set of operations. When you have done this it becomes possible to see the duplication in your code and you start solving the more general problems. It is sad that the best piece of software engineering advice that I know of is to write short functions, but, well, there it is. Don’t spend it all in one place.
Do The Right Thing
This principle sounds funny when stated directly, after all who is advocating doing the wrong thing? And what is the right thing to do, anyway?
The point is that in the process of developing software I am always facing the following situation: I can cut corners now, hack my way around a bug, add another special case, etc. OR I can try to do the right thing. Often I don’t know what the right thing is, and then I don’t have a choice but to guess. But more often, I know the best solution but it requires changing things. In my experience every single factor in the software development process will argue for doing the wrong thing: schedules, managers, coworkers, and even, when they get involved, customers. All of these groups want things working as soon as possible, and they don’t care what is done to accomplish that. But no one can see the trade-off being made except for the programmers working on the code. And each of these hacks seems to come back like the ghost of Christmas past in the form of P0 bugs, and I end up doing the right thing then under great pressure and at higher cost then I would have done it before.
A lot of times doing the right thing means solving the more general problem. And it is an odd experience in computer programming that often solving the more general problem is no harder then solving the special cases once you can see the general problem.
There is a lot of advice that argues the opposite. This line of thought says just throw something out there, then see how it is conceptually broken, then fix it. This argument is perfectly summarized in the “worse-is-better” discussion, and I don’t have much to add to it. Except to say this, I think that worse-is-better is a payment scheme. With worse-is-better you get 85% of a solution for dirt cheap, and the remaining 15% you will pay in full every month for the rest of your software system’s life. If you are writing software that you know will be of no use tomorrow, then worse-is-better is a steal, (but you might want to consider quitting your job). If you are writing software that will last a while you should do the right thing.
Reduce State
You may have heard that Amdahl’s law is the new Moore’s law and that by the time Microsoft finishes the next version of Windows computers will have like holly shit 80 fucking cores. This means that in five years when your single threaded program is going full tilt boogie it will be using all of 1/80th of the processor on the machine. As a semi-recent computer science grad. student my opinion of concurrency is “neato.” But I notice the old timers at work have more of a “we are so totally fucked” look about them when they talk about it. I think the reason for this is this: if x is a mutable object then the following doesn’t hold in multithreaded program:
x.equals(x)
Like everyone else, I am guessing that the end game for all this will be a massive reduction in mutable state. Those functional language people are definitely on to something. But those of us who still have to program in dysfunctional languages during the day need a more gradual path. The question is, if mutable state is bad, is less mutable state less bad? or do I have to get rid of it all?
I don’t know the answer to this. But for a while now, I have been trying the following. Whenever possible avoid class variables that aren’t declared final. See functional programming gets rid of side-effects altogether, but I know if this is necessary. Inside a function the occasional i++ really isn’t that confusing and I am not sure I want to give it up just yet. The reason is that method-local variables have no publicly accessible state, so as long as I am writing short functions this temporary state shouldn’t be a problem. By making x immutable you ensure that x.equals(x). This also makes it very easy to prevent invalid states, just ensure that either the user provides valid inputs to the constructor or the constructor throws an exception—if you do this, and don’t have mutable state, then you are guaranteed no bad states.
I haven’t figured out yet how to make all my members final just yet (or I would probably be using haskell). It seems to me that if I want to change a User’s email address then I need to be able to call user.setEmail(). That is because the state of the email address is real state out there in the world that I have to model in my program. So the domain model retains its state. But as yea of the Java world know, the domain model is not all the code, oh no. We still have business objects, and persistence objects, and gee-golly all kinds of other objects. And guess what–99% of the state in these objects can go. And when it does everything gets better.
But I am only starting with this concurrency thing. I am reading this book, which is awesome. In it you can learn about all kinds of disturbing things like how the JVM has secretly been scrambling the order of execution of your code in subtle ways and things like that.
Know Your Shit
Just as the workable solution is always the last thing you try, the impossibly to diagnose bug is always in the software layer you don’t understand. You have to understand all layers that directly surround your code—for most programmers this begins with the OS. If you do low level programming you better know about computer architecture too. But this idea is bigger that just catching obscure bugs, it has to do with finding the solution to hard problems. Someone who is familiar with the internals of an OS has enough of the big ideas under their belt to attack most large software problems.
Web programmers know that all performance problems come from the database. Naturally when you first see a performance problem in a database backed application, you want to do some profiling and see where in the code the time is going. After all, isn’t this what everyone says to do?. You can do this, but you might as well just save yourself the time and just log the queries that are issued on that code path, then get the database execution plan on each, you’ll find the performance problem pretty quickly. The reason is simple: data lives on disks and disks are (say) 100,000 times slower than memory. So to cause a problem in java you have to be about 100,000 times more stupid shit than to cause a problem in SQL. But notice how the gorgeous relational database abstraction layer has broken down and in order to solve the problem one has to think about how much data is being pulled off the disk to satisfy the query. The point is that you can’t stop at understanding the relational part, you also need to understand the database part.
The larger problem is what should we be learning to be better at this. I know that the following things will help because they have helped me:
- Learn a functional programming language
- Learn how operating systems work
- Learn how databases work
- Learn how to read a computer science paper
- Learn as much math as you can (but which math…)
Unfortunately t is virtually impossible to say what will not help you solve a problem. Will knowledge of good old-fashioned AI help you write enterprise software? It certainly might when you implement their 400,000 lines of Java business rules templates as 2,000 lines in a prolog-like business rules system. Likewise, it isn’t every day that I need to integrate at work, but when I have the payoff has usually been big. If you asked me if studying something very useless and different from computers, literature, say, would help you to solve problems, I couldn’t tell you that it wouldn’t. It might be less likely then studying operating systems or databases to pay off, so there might be some opportunity cost, but I couldn’t tell you that the next big advance wouldn’t come from someone who had divided their time between programming and literature. I think that that is pretty much the state of our art, we don’t even know what the framework in which the new ideas will come, let alone what they might be. I’m not sure if that is exciting or pathetic.
[1] “Ruby is a butterfly“. Wow dude, go outside. Look at any of the beautiful creatures on the earth. Now go back in and look at your computer. See much resemblance? Me either.
Just because we are better at it doesn’t mean we are good at it, and even if we are good at it that doesn’t make it a good idea. Anyone who has looked at a JSP that contained equal parts HTML, CSS, SQL, Java, and Javascript has a fair idea what the source for WEB programs looks like. But the produced output, like all TEX output, is absolutely stunning.
[3] Wearing sunscreen is good advice too, but computer programmers are probably the least at-risk sub-population for skin cancer since most of them aren’t white and none of them seem to get outside enough. If in doubt write short functions while wearing sunscreen, but if you have to give up one, lose the sunscreen.
Scott Hickey | 10-Oct-06 at 7:52 am | Permalink
I have been working on a large project that is mostly written in Java but one component was written in Groovy ( up to about 40,000 line - including tests). IMHO, the work with Groovy has been really successful.
I think the fail fast is really important. For the Groovy component, we started with a unit test and component test framework first, then wrote the application code. It’s frustrating for some developers at first but once you have good feedback systems in place, it’s amazing how much more pleasant development become. Personally, I didn’t miss the type checking. The small value it provides gets lost in the positive benefits provided by unit tests and component tests.
Being a long time Java programmer, I was surprised to find how much nicer Groovy was for writing less code and making the code easier to read. Furthermore,I would have thought lack of IDE refactoring would make it hard to do the right thing, but it didn’t. I now think that comprehensive tests have been more of an enabler for tackling refactoring than IDE support.
Very good blog - most all of your points really resonate with me. Alot of what you describe sounds like hard work. It should. It really takes work to educate oneselft about what’s happening under the covers and then apply that knowledge to produce quallity software.
Five Principles for Programming » Another Blogger | 10-Oct-06 at 10:18 am | Permalink
[…] My current job-hunting is forcing me to look hard at my programming/development skills. I enjoy reading things like Programming Pearls and the Pragmatic Programmer, and Empathy Box’s 5 Priciples for Programming was likewise an interesting read today. Check it out. tagged as: programming, softwaredevelopment Related Posts: Things Programmers Should Know About Marketers […]
Danny deSousa | 10-Oct-06 at 11:09 am | Permalink
Nicely articulated. I really had a good laugh reading the “Reduce State” section of your blog. If you were to ask me the question about concurrency I would just plainly state that we’re f**ked… no glazed look from me, just pure painful honesty.
La Guarida de Boomer » Para nosotros los programadores | 10-Oct-06 at 11:30 am | Permalink
[…] Encontré un sitio con una entrada que vale la pena leer: Los 5 principios de la programación. […]
Slava Pestov | 10-Oct-06 at 12:53 pm | Permalink
What makes you think that people who like dynamically typed languages (note: there is no such thing as “dynamic languages”) have never worked on large projects?
It would be more accurate to say that the vast majority of Java programmers have never worked on anything non-trivial, even if they have worked on large projects. Your average corporate IT web app doesn’t have any sophisticated algorithms in it at all.
jay | 10-Oct-06 at 1:18 pm | Permalink
Hi Scott,
Yeah I agree that Groovy, Python, and Ruby are way ahead in terms of simplicity, expressiveness and usefulness. All that bothers me is that dynamic typing is usually portrayed as a benefit instead of a sacrifice. I mean what we want is Groovy/Python/Ruby where the types are infered and checked all at once at “compile”-time. Since we don’t have such a thing (and certainly can’t without changing those languages) it makes sense to argue that there are areas where the pain of explicit typing just isn’t worth the benefit of compile-time type-checking.
What I want to understand is how much of the niceness of these languages comes from the fact that types can’t be determined at runtime and how much comes from the fact that they were developed collaboratively.
jay | 10-Oct-06 at 1:34 pm | Permalink
Hi Slava,
“Dynamic languages” is not a term I invented. If you don’t like it you can substitute “dynamically typed languages.”
What makes me think that most people who use dynamically typed languages haven’t worked on large dynamically typed projects is that their popularity is fairly new, and fairly non-commercial so there hasn’t been time. This shouldn’t be contriversial: take the packages installed on the average Debian/Ubuntu system, count how many are done in Python/Ruby vs. how many are done in c/c++.
It is certainly true that the vast majority of all programmers do not develop non-trivial algorithms. This is one of the successes of software development (you don’t need to implement a b-tree to use one). But I don’t think it is at all accurate to say that the vast majority of Java programmer’s have never worked on anything non-trivial unless you mean trivial in the mathematician sense (i.e. possible). Developing large software systems is difficult. It isn’t difficult because people use Java or because people are all stupid. It is just hard. It may not be the kind of hard that appeals to you (it doesn’t particularly appeal to me), but if you think it isn’t hard then I think you probably don’t know what you are talking about.
Whitespace | 10-Oct-06 at 2:26 pm | Permalink
5 Principles For Programming…
…
Adrian | 10-Oct-06 at 2:27 pm | Permalink
I count six.
jay | 10-Oct-06 at 3:05 pm | Permalink
Ha ha, wups. It actually started out as three principles for programming, but then I couldn’t cram everything into three. Maybe under the learn some math section I should add a link to Sesame Street.
Nate | 10-Oct-06 at 4:24 pm | Permalink
This is one of the best articles on programming that I’ve read. I have to agree with all of the points that you’ve set forth… great read.
dons | 10-Oct-06 at 6:20 pm | Permalink
“method-local variables have no publicly accessible state, so as long as
I am writing short functions this temporary state shouldnt be a problem.”
Congratulations, you’ve just invented state monads!
This is the very essence of encapulating side effects such that they
can’t mess with the rest of your code. Mutable variables in Haskell
(such as STRefs) work exactly this way.
Brian Slesinsky | 11-Oct-06 at 12:48 am | Permalink
In answer to how do you get rid of user.setEmail(): Well, just like in a source control system, whenever you want to change something you just create a new version. (Which means also creating a new version of whatever points to User, and so on recursively until you get to the root of your domain model.)
I’ve tried this in Java and it can be done, but found that getting rid of mutable state didn’t make the code any easier to write. It just replaces bugs caused by mutibility with other bugs caused by using the wrong version of something.
Anonymous | 11-Oct-06 at 9:09 am | Permalink
5 Principles For Programming…
Here are a few things I have learned about programming computers, in no particular order. I didn’t invent any of them, and I don’t always follow them. But since nobody seems to know very much about making good software, it makes sense to try to dis…
Anonymous | 12-Oct-06 at 10:47 am | Permalink
Fail Fast is good, but Design by Contract is better
a | 12-Oct-06 at 11:45 am | Permalink
Closing the underline
meneame.net | 12-Oct-06 at 11:54 am | Permalink
cinco principios de la programación…
En este artículo (en inglés) se describen 5 principios para un buen desarrollo: Fail Fast, Write Less Code (and Don’t Repeat Yourself), Computer Programs Are For People, Do The Right Thing, Reduce State, Know Your Shit. Extenso pero interesante….
Confluence: CustomWare Staff - Karl Santa | 12-Oct-06 at 3:46 pm | Permalink
5 principles for programming…
This is a link from TSS which I found really interesting……
Alex | 12-Oct-06 at 9:48 pm | Permalink
An amusing read, thanks
All common sense, but so easily forgotten/ignored.
Urubatan`s Weblog » Links do Dia! | 13-Oct-06 at 5:16 am | Permalink
[…] Empathy Box :: 5 Principles For Programming Sztywny Blog - Stiff asks, great programmers answer Enterprise Java Community: Testing Concurrent Programs Java continuations e NIO, o casamento perfeito A grande maioria dos links sera sobre java […]
Thomas Mäder | 13-Oct-06 at 6:35 am | Permalink
> By declaring x final you ensure that
> x.equals(x).
Just nitpicking, but the above is not true, all it ensures is that x == x (again, x may be an Object with mutable state).
Liked the post, otherwise (a lot).
sri | 13-Oct-06 at 6:47 am | Permalink
wonderful read. took me back to school days where we used to have lots of fun with programming.
Quest3D|Log » Blog Archive » Readup: some words for the weekend | 13-Oct-06 at 8:30 am | Permalink
[…] Game-industrie stevent af op record-jaar - The first article in Dutch so far, a little news snippet about the game industry heading towards a record-breaking year in terms of sales. Nice books on the game industry - Related Quest if you want to develop anything close to a game with it. Don’t Listen To The Fans - Article why not to listen to your ‘fans’ if you have created a game. That’s right. NOT listen to your fans. Quite a fun read. Women in Gaming - The hardcore gamers’ worst nightmare. A woman. Playing a game . 5 Principles For Programming - I think some or all may be applicable to Quest3D too, nice read nonetheless. […]
Urubatan`s Weblog » links for 2006-10-14 | 13-Oct-06 at 5:35 pm | Permalink
[…] Empathy Box :: 5 Principles For Programming […]
Labnotes » Rounded Corners - 45 | 15-Oct-06 at 1:32 pm | Permalink
[…] 5 Principles for Programming. Duh. But you knew that already, otherwise, go read it again. […]
ryan king | 15-Oct-06 at 6:29 pm | Permalink
“Somehow simple statements/programs/explanations/models are more likely to be correct.”
I think this is best explained by Occam’s Razor [http://en.wikipedia.org/wiki/Occam%27s_razor]: “In short, when given two equally valid explanations for a phenomenon, one should embrace the less complicated formulation.”
Model Reality » Blog Archive » 5 (zero-indexed) Principles For Programming | 16-Oct-06 at 2:00 pm | Permalink
[…] Empathy Box :: 5 Principles For Programming […]
links for 2006-10-16 « Ashish Kulkarni’s Journal | 16-Oct-06 at 3:23 pm | Permalink
[…] 5 Principles For Programming “since nobody seems to know very much about making good software, it makes sense to try to distill a little wisdom when possible.” […]
John | 16-Oct-06 at 4:14 pm | Permalink
“Web programmers know that all performance problems come from the database.”
Using a profiler, I found that only ten percent of the total time to display a JSP in my J2EE application was spent querying the database and building persistent objects. The other 90% was spent on in-memory operations required to render the page. This is a commercial application that was built using industry best practices by ten of the best software developers I have ever worked with.
I have seen bad developers waste a lot of resources optimizing the wrong code. The 7th principle - forget everything you think you know about performance bottlenecks.
Mike | 16-Oct-06 at 4:44 pm | Permalink
On “Fail Fast”, that’s one thing I really loved about my limited time I was forced to use Standard ML in a CS class — serious compile-time type checking catches so many silly little bugs early.
jarred | 16-Oct-06 at 6:57 pm | Permalink
编程的六个原则(翻译)…
编程的六个原则…
jay | 17-Oct-06 at 12:21 am | Permalink
Brian–I agree that it is Occam’s razor, although I don’t think that Occam’s razor really explains much of anything, it is just the observation that simple things are more likely. I actually had substantially more about this, and talked about Occam’s Razor and MDL explicitly, but then I realized it would work better as a seperate entry.
John–Yes but those numbers are for a page performing well. The poorly performing page is usually from the db. It is hard to spend a lot of time in a JSP and not notice it.
Thomas–you are totally correct. Thank you for catching that. The Goetz book I mentioned before gives the conditions for immutability nicely, stating that an object is immutable if
1. Its state cannot be modified after construction.
2. All its fields are final and
3. It is properly constructed (the this reference does not escape during construction).
James Watson | 17-Oct-06 at 9:40 am | Permalink
The points about state are very good to point out as they are often unknown/ignored in the Java universe. I feel that unless a member needs to be non-final, it should be non-final. I wish the compiler would follow method calls in the constructor to check for initializing finals, though.
Another technique is to use stateful objects that never escape the stack. There is no concurrency issues with this and in fact, future versions of Java will (if all goes well) actually create such Objects on the stack or even extract their members onto the stack.
But again, I completely agree with reducting state to the absolute minimum. If you do so, it will be much easier to refactor code to be threadsafe if needed in the future.
James Watson | 17-Oct-06 at 9:43 am | Permalink
“I feel that unless a member needs to be non-final, it should be non-final.”
That should read:
I feel that unless a member needs to be non-final, it should be final.
David House | 19-Oct-06 at 8:51 am | Permalink
Really interesting post. I’m a Haskeller myself, so I’m in total accord with things like your advocation of static typing. The last section was probably the most interesting — I can claim knowledge of a functional programming language, I’ve read a few papers and am about to start a maths degree, but kernels scare me and my database experience goes about as far as MySQL.
I think I’ll be buying some books.
Thanks again.
bugfox blog » Blog Archive » 5 Principles For Programming | 20-Oct-06 at 7:42 am | Permalink
[…] Simple but deep: Empathy Box :: 5 Principles For Programming […]