Sunday, July 30, 2006

 

Quite a week...

Monday: mostly traveling, which means catching up with some papers. Among others, I re-read "Refactoring the Aspectizable Interfaces: An Empirical Assessment", IEEE Transactions on Software Engineering, October 2005. I'm getting more and more interested in Aspects as a design concept, beyond the usual stuff (tracing, transactions, etc). This paper is an interesting step in the right direction.

Tuesday and Wednesday: teaching Win32 and Windows CE System Programming.

Thursday and Friday: consulting on early design of a PDA application. One day went into architectural issues, the next was mostly about user interface. It's hard to make a PDA application truly usable. I think we did a pretty good job.

It's boring to have dinner alone :-), so I filled some time reading a few more papers. Got a reference from the paper above: "N Degrees of Separation: Multi-Dimensional Separation of Concerns" (Proceedings of ICSEE 1999). Quite interesting, and some of the concepts reach beyond AOP. I've been thinking for a while about design guidelines for partial classes and extension methods in .NET, and this paper has given me a few interesting ideas. One of the authors (Harold Ossher) also wrote the very first paper I read (back in 1995, I think) that was somehow related to AOP ("Subject Oriented Programming", Proceedings of OOPSLA 1993). While looking for that paper on my notebook, somehow I ended up re-reading an old article ("Integrating Independently ­Developed Components in Object ­Oriented Languages" by Urs Holzle, Proceedings of ECOOP 93). It's funny how a paper that is 13 years old can be so actual. Most of the problems identified by Holzle are still true today, and AOP is only a partial step toward a solution. Again, I couldn't help thinking that AOP is somewhat too ambitious, and that a simpler paradigm should be sought, borrowing from the many good ideas that AOP is bringing forward.

Saturday: I've been in Reggio Emilia to see an exhibit of one of my favorite artists, Arnaldo Pomodoro. Only a few works were shown, but the man is always amazing. Got a gift, a book that I've been skimming more than once :-) in bookstores: "Ultramarathon Man" by Dean Karnazes. It's a nice read, and the first 150 pages flew by in the evening.

Sunday: I had to finish the book :-). I only had another 150 pages left, so it didn't take long. Every now and then, I had a short break to answer some emails and write a little C++ code for a meta-programmed (aka compile-time) balanced search tree, which should end up in an article sooner or later (I'm writing all this with another author, and we're definitely not in a hurry :-). Shortly before lunch, the book was over, and I really wanted to get out and run :-). However, I had some work to do after lunch: the final review of the copyedited version of my IEEE paper is due soon. I spent a couple of hours going over the text, trying to find a good reason not to get out and run :-). I did have good reasons:
1) it was hot as hell
2) I wasn't in a known place, I didn't know the surrounding, so I would probably end up running in some unpleasant place with cars racing around
3) I didn't have the right shoes with me
4) I didn't have anything to bring some water with me - see also reason 1 :-)).
Must have been the book :-), but in the end I decided those were pretty lame excuses :-) and went out for a short run (about 10Km). Well, all the above was so true :-), but I was happy anyway. Despite some smog, the shoes, the heat, etc, I managed to run at about twice my usual pace. Of course, I usually run over hills, and I was in flatland :-) today, which explains why.
Came back happy anyway, and after a good shower I gave the finishing touch to that C++ metaprogramming code.

OK, now I guess I'll take Monday morning off :-)))

Sunday, July 16, 2006

 

Quantitative Design Methods

Lets face it: most people do not design software; they code their way through it. There are many (bad :-) reasons for that, including the trivial fact that lot of decent coders are not inherently good at designing software. But leaving those reasons aside, there is an important difference between software and other engineering disciplines. In other disciplines, one of the reasons to go through a design phase is that you can get some quantitative data to back up your decisions. Those quantitative data can be useful to answer some questions, like "if you build that bridge with that shape and using those materials, how much weight / wind / etc can it sustain before breaking", or "if we place components this way on the PCB, what would the thermal distribution be", and so on.
Of course, we have interesting questions in software too. "If you build the application using J2EE and Entity Beans, using that specific application server on that specific hardware, under your architectural decisions, how many transactions per second can we sustain (given a probability distribution of transaction types)?".
It's usually hard to answer those questions, unless you've done something very similar in the [near] past. Most people will try to answer by prototyping (I've done that quite a few times), meaning you quickly build something that may exhibit similar performance figures and try that out, or by ignoring the problem. They will build the system ignoring performance, usually adopting a specific technology and/or architecture out of trust, experience, faith :-) or whatever, and then add more hardware resources if they can't keep up with the load (assuming, of course, that it makes economic sense to add iron, that the architecture is indeed scalable, and so on).
Of course, if we had better design methods and tools, we could get some serious help. That would make software design much more useful, software architecture choices more visible and justifiable / justified, and so on (dunno what the agile guys would do at that point; move a little more toward design and a little further from code? But what about the need to know a little more about most users story to make the proper architectural decisions? Oh well... :-).
There are, of course, several attempts to come up with more quantitative methods in software. In the hard-real-time domain, schedulability has got huge attention over the years, and what is really missing now is an end-to-end (design - simulation - coding [not code generation] - profiling and back) tool for the masses. For the enterprise systems, IBM used to have proprietary data and tools, but that hardly qualifies as quantitative design.
A very interesting approach has been developed at University of Sidney (see "Design-Level Performance Prediction of Component-Based Architecture, IEEE Transactions on Software Engineering, November 2005). What the authors did was to define an abstract model of a J2EE container, develop an application-neutral benchmark that can be used to assess (once and forever) some parameters of a real container running on some real iron, and combine that application-neutral model with an application-dependent portion. The application-dependent portion is largely design-driven: you don't need to implement any code. The results, as published, are quite impressive. For a relatively simple application (barebone Online Stock Trading), implemented in J2EE using 2 different architectural patterns and on two different J2EE containers, the simulation was basically within 10% of the actual results. The real innovation, of course, is their ability to assess all the container-dependent parameters just once, with an application-neutral model.
As usual, they didn't give enough details to replicate everything in your lab :-), maybe with different technologies. In some sense, in a proper market that should fall on the container vendor (don't hold your breath :-), but when you have a home-grown architecture (I'm thinking of many reactive systems) it would be a huge boon to have a similar approach really working.
The authors use methods from queuing network theories, and reference a book that I've bought time ago but never had time to read ("Scaling for e-business" by Menasce' and Almeida). Despite the low-profile title, the book gives the subject a serious look, and uses a similar (queuing network) approach, although without the application-neutral / application-dependent separation. I guess I should set aside a little time and actually read it :-).

Wednesday, July 12, 2006

 

Self-fulfilling expectations

A reader reminded me via email that I've been using the expression "self-fulfilling expectation" twice when answering comments from the agile crowd (see the recent post on TDD and an older post on project management) without ever really explaining what I meant.
A self-fulfilling expectation (also, self-fulfilling prophecy) is a belief that, when held [by enough people, in some cases] works to make itself true. A popular example comes from finance: for some unjustified reasons, a number of people start to believe that a traded company has financial troubles; they start to sell stocks, the company value begins to drop, they sell at even lower prices, and so on; in the end, the company may experience real financial troubles. For a variation, see the wikipedia.

What has this to do with software engineering? Well, quite a lot. I'll give an example, using non-code artifacts, say diagrams. Of course, it's just one among many possible examples.

Some people start with an initial belief that diagrams are a useful way to reason about some problems (if they're naive, they may think all problems, but let's skip that). They believe that having an abstract view of the code (without all the details of code) makes some reasoning simpler. They start to use diagrams, they hone their ability to create useful diagrams. They also keep diagrams alive as the project grows: not using reverse-engineering tools, because that would quickly make the diagram useless (full of details, basically a graphical view of code, not a model). Since they believe that diagrams must be abstract views, they make abstract models, so small changes to the code won't change the diagrams. Since they believe that some reasoning is simpler on diagrams than on code, when the change is so big as to impact the diagrams, they will first think on the diagram, find a good solution by playing with it, then implement the change in code. Anyway, the diagram will be kept alive, so at any time, they can switch the reasoning from code to diagram. Diagrams will probably prove to be also a good communication device. Naturally, there will be a cost (sometimes you won't even see an immediate value in keeping the diagrams alive) but in the end, the diagram will prove itself really useful, and they will more than pay back, just as expected

Some people believe that the only useful artifact (long-term) is code. They may sketch some diagrams in the beginning (or maybe not), but they won't keep them alive too long. As soon as they don't see immediate value on keeping the diagrams alive, they will scrap them. As they don't value diagrams too much, they won't invest much in making useful, long-lasting diagrams; in some cases, they won't even spend time learning something like UML in depth, learning maybe just the basic syntax. Therefore, they won't even be able to model much using diagrams (which immediately makes them useless, already fulfilling the expectation). Given the cursory knowledge of the notation, it will be hard for a group of such people to use diagrams as an effective communication tool (again, making it pretty useless, and fulfilling the expectation). If diagrams are not entirely disposed, they will soon get totally out of synch with code (since even large changes are done directly on code, not thought on diagrams). Therefore, they will give less and less value to the project, finally becoming useless, just as expected.

Note that you can't just say stuff like "use diagrams until they add value", because that implies that as soon as you don't see a short-term value you'll scrap them. In two weeks (or 2 months) they could prove exceptionally useful, if you keep them alive (prophecy 1). Of course, they won't be if you don't (prophecy 2).

The fact is, what we believe tends to get true. We come at points where an option is logical only within a belief system, and acting according to our beliefs makes those beliefs true. More on beliefs and values in Software Engineering another time :-)

This is one more reason why I don't like fanatism of any kind. Fanatics tend to close themselves in self-fulfilling, self-feeding belief systems, and lose the ability to see beyond that. My simple recipe? Keep your beliefs flexible - it's science and technology, not religion. Understand that there is not a single perfect approach to any problem, although we can try to find a specific almost-perfect approach to any specific problem. Finally, if you really have to believe in something, believe in what you would like to get true :-).

Tuesday, July 11, 2006

 

[Late] Weekend Readings, Meaningful Coincidences and Some Real Work

I'm always reading a lot, although I'm constantly behind :-), with journals and books piling up. I've spent a little time reading during the weekend (and yesterday and this morning as well), picking up random unfinished magazines from one of the stacks lying around. I'll skip on two articles on UML usage in real projects - they didn't add much that wasn't already largely known. A somewhat interesting paper was "Emphasizing Human Capabilities in Software Development" (IEEE Software, March/April 2006). The authors used a personality test (Cattell's 16PF) to match people to job (analyst, programmer, etc). I'm relatively familiar with other tests (like Myers-Briggs) but didn't know about the 16PF, so I even spent some time to get an online test and guess what, after I bring the results back into the author's model, it turns out I'm pretty good in most software development roles ;-). My ideal position would be, according to the model, "team leader". It seems I lack discipline (which in this context doesn't mean self-discipline, but something more like dutifulness), which I guess is true :-)). I don't really agree on some parts of their model though. For instance, Abstract Thinking is discouraged for people involved in Analysis (that includes, in their model, the Analyst, the Designer, etc), which seems extremely weird, and strongly tied with a notion of analysis being a faithful, non-creative gathering of requirements, which is far from true (more on this another time).
Another somewhat interesting paper was "Prepare Your Mind for Learning", Communications of ACM, September 2005. I loved the concept of metacognitive miscalibration, somewhat less the examples. The suggestions were all good but not very original. I'd like to link this with the concept of filtering (see the bottom of one of my old posts). For some reason or another :-)), that reminds me of some virulent comments :-) on my previous post on test first :-).
Another somewhat interesting paper was "Achieving Scalability in Real-Time Systems", IEEE Computer, May 2006. The authors mentioned a wait-free mechanism for concurrent read/write (Cyclical Asynchronous Buffers), and got me interested enough to dig further. There is even a working implementation of CABs on the E.R.I.K.A. website at Scuola Superiore Sant'Anna (the author is also from there). Well, it's hard not to miss OOP when you read that C code, but anyway, that concept reminds me an interesting pattern (sharing 90% of the underlying idea; that's what makes it a pattern :-), "Resource Exchanger: A Behavioral Pattern for Low-Overhead Concurrent Resource Management", in "Pattern Languages of Program Design Vol. 2".
Interesting coincidence. I teach that pattern, among others, in a course on OOP/OOD for embedded systems. In these days, I'm also working on some teaching materials for embedded systems. I'm extending my "Win32 System Programming" course with a lot of stuff on Windows CE, which has been a constant theme for me in the latest months. It's funny how many things we routinely teach as "good programming style" in C++ makes much more sense for embedded systems (which, after all, should not surprise anybody :-). For instance, under CE the compiler is actually moving static const data to a read-only memory segment (as many "embedded" compilers do). That makes the idea of casting away const on a const reference to a const object dangerous enough :-) to justify the unspecified behaviour label in the ANSI/ISO standard :-), and is indeed my standard explanation (although, I've to admit, it tends to get blank stares from programmers that have never worked on embedded systems :-).

This page is powered by Blogger. Isn't yours?