Monday, October 31, 2005
Teaching SOFTWARE Project Management
Despite the large number of requests, I've never committed myself to create a set of PM slides. For more than a few years, I've been firm into telling that I knew enough to run a successful project, and even enough to advise on how to run a specific project, but not enough to teach how to do it in general (which is what I would expect from a PM course).
In the last year, I've spent more and more time thinking on what I could actually teach - valuable, modern, software-specific techniques that I've tried in the real world and that I can trust to work. It turned out that I knew more than I thought, but also that I couldn't teach those techniques without first teaching some (even more fundamental) conceptual tools, like Armour Ignorance Orders or Project Portfolios or Option Thinking, and so on.
In these days I'm polishing the slides I've created, and trying to create a natural bridge between those slides and some of my material on Requirements Analysis. This is probably a good chance to review that material as well, along the lines I've envisioned a few months ago. So, very soon I'll have a new, short, hopefully fun course on PM appearing on my course catalogue.
The posts that could have been
Past week has been so busy that I had no time to write anything. So here are a few thoughts and episodes that will never see the light :-) :
- How the lack of system thinking can turn a well-intentioned optimization into a pessimization. Inspired by some troubles buying tickets :-)
- How the wrong attitude in an otherwise good software engineer can harm his career and ultimately his group (well, I'd better keep this for myself anyway :-)
- Code reviews, and the need for a cultural change to get over the blame game.
- How space affects creativity. Or, can you see the affordances built in your working environment? What do they tell you?
- Early thoughts after teaching a short seminar at University of Trieste.
Anyway, this week should be lighter :-), so I'll probably post something slightly more interesting here :-).
- How the lack of system thinking can turn a well-intentioned optimization into a pessimization. Inspired by some troubles buying tickets :-)
- How the wrong attitude in an otherwise good software engineer can harm his career and ultimately his group (well, I'd better keep this for myself anyway :-)
- Code reviews, and the need for a cultural change to get over the blame game.
- How space affects creativity. Or, can you see the affordances built in your working environment? What do they tell you?
- Early thoughts after teaching a short seminar at University of Trieste.
Anyway, this week should be lighter :-), so I'll probably post something slightly more interesting here :-).
Monday, October 24, 2005
UML and Web Applications
If you want to model the static structure of the website, you can use the class and component diagram, with custom stereotypes. Jim Conallen has published a few articles on that starting in 1999.
However, what I've found most useful is to show the activities carried out in each layer, the sequence of calls, the synchronization requirements if some can go in parallel or are asynchronous (like credit card validation, etc). In this case, you can adopt the activity diagram, so often forgotten but still one of the most useful UML diagrams.
Swimlanes can be used to represent tiers or, if you have a complex architecture, components within each tier. You can then easily show a browser calling into the PHP frontend, which can extract parameters and call a stored procedure, and so on. See this example to get some hints.
Activity diagrams are much more powerful than that: you can use object flow to show how some artifact is passed around between activities, how its internal state would evolve, and so on. Moreover, with UML facilities, you can easily model "reusable" activities that can be plugged into several different workflows.
Friday, October 21, 2005
Designed Affordances as Communication
Have a look at Designed Affordances as Communication, where Norman talks a little about affordances and then introduces a concept from Clarisse Sieckenius de Souza: interaction is not a communication with technology, but communication between the designer [of that technology] and the person [user], where the technology is [just] the medium. He then goes ahead with another interesting concept, "Why Stories Are Superior to Logic", which is brilliant although (I'm afraid) a little hard to practice. Overall, I can't say the piece is one of the best Norman's writings, but those two concepts alone make it a must read...
This is my first post decorated with invisible semantic tags! I know I won't see a custom search engine anytime soon, but hey, I could always persuade someone to write me one in php :-). More seriously, if you have any visual issue on some weird browser :-), please let me know (unless the issue is so serious you can't see this :-))
Wednesday, October 19, 2005
The Semantic Blog (or: the revenge of structure :-)
Blogging makes some portions of a traditional (read: old-fashioned) website like mine so obsolete. The "news" section is the first candidate, and the "links" section is just about second. Links age, nobody has enough time to keep them current; and I do mean current, not simply valid (which can be easily automated).
Blogging makes suggesting new links a snap, and thanks to the ephemeral nature of a blog (see my Blogging as Destructuring) nobody expects you to keep the links updated.
Still, something is seriously missing. In a traditional website, users could easily visit the "links" page a get a list of (hopefully relevant) websites. In a modern blog, users would have to sift through all my blurb looking for links. Just about the same for news: I make a few announcements here, like a new release of my UML book, but you have to look for them.
An easy step forward, well within reach, would be to decorate portions of the text with semantic information. We don't need to wait for all the semantic web hype to get true: we can just grab the low fruits right now. Since a well-mannered browser must ignore unknown HTML tags, we can easily add a new one, like <semantic> and use it to (invisibly) decorate text, like in <semantic type="announcement">some announcement</semantic> which would render just as "some announcement". Then, a customized search engine could easily look for posts belonging to specific categories, like links, announcements, etc. Obviously, a post may fall into more than one category.
Naturally, the "type" attribute would open for extension, that is, anybody could invent a new type, like "free time", "deep thought", etc. To avoid any maintenance of the search page (where I would expect to find a combo box for category selection), the search engine should keep track of available types (for that blog) and build the combo box appropriately. This is basically a user-defined ontology, a.k.a. a Folksonomy.
The only trouble is that building all this stuff by myself sounds like work :-). I must pass on this suggestion to the Google guys. After all, I'm using their blogging technology for free, and they may find this idea remotely interesting...
Blogging makes suggesting new links a snap, and thanks to the ephemeral nature of a blog (see my Blogging as Destructuring) nobody expects you to keep the links updated.
Still, something is seriously missing. In a traditional website, users could easily visit the "links" page a get a list of (hopefully relevant) websites. In a modern blog, users would have to sift through all my blurb looking for links. Just about the same for news: I make a few announcements here, like a new release of my UML book, but you have to look for them.
An easy step forward, well within reach, would be to decorate portions of the text with semantic information. We don't need to wait for all the semantic web hype to get true: we can just grab the low fruits right now. Since a well-mannered browser must ignore unknown HTML tags, we can easily add a new one, like <semantic> and use it to (invisibly) decorate text, like in <semantic type="announcement">some announcement</semantic> which would render just as "some announcement". Then, a customized search engine could easily look for posts belonging to specific categories, like links, announcements, etc. Obviously, a post may fall into more than one category.
Naturally, the "type" attribute would open for extension, that is, anybody could invent a new type, like "free time", "deep thought", etc. To avoid any maintenance of the search page (where I would expect to find a combo box for category selection), the search engine should keep track of available types (for that blog) and build the combo box appropriately. This is basically a user-defined ontology, a.k.a. a Folksonomy.
The only trouble is that building all this stuff by myself sounds like work :-). I must pass on this suggestion to the Google guys. After all, I'm using their blogging technology for free, and they may find this idea remotely interesting...
Business, planning, uncertainty
I used to see "rigid" plans as a good thing about 10 years ago, but that was a different world. Flexible planning requires better management skills, but is much more efficient and open to optimizations. This is true for any kind of endeavor, from planning my hectic schedule :-) to managing a complex, uncertainty-ridden project.
Next week, after 3.5 days teaching and consulting at a customer's site in Udine, I'll be teaching UML at the University of Trieste (lesson 1 of 3). There is a lot of bureaucracy and paper-stuff involved, but hey, that's part of the business too :-)).
Monday, October 17, 2005
Hiding details you can't hide
In a previous post, I mentioned the perils of abstraction, and how we can safely abstract away what we know, not what we don't know.
Unfortunately, language designers often want to hide to the ignorant programmers (that is, the rest of us) some "details" that they deem to hard to understand or master, or too boring to deal with continuously, and so on. They are often well-intentioned (although a little patronizing :-), but the result is often a huge mess.
Consider COM: it started as an easy way to write language-independent (sort of) macro-components in C++. Initially, there was no notion of a threading model: you should have been careful, on the producer and consumer side. That was it.
When VB came along with its support for COM, they decided that the programmer was too stupid to master concurrency (not to mention the thread affinity of old ODBC drivers and the like) and they invented the threading models. That was a well-intentioned bad idea :-), because even today, just a minority of programmers really understand the subtleties of COM threading models ( quick check: can you really explain the difference between choosing "free threading" or "both" in the ATL wizard? :-).
Now, when C# and .NET came along, someone must have decided that exposing the difference between value types and reference types all the time would have been bad. Indeed, I like the idea of implicit boxing, as explicit boxing a-la Java is a pain in the @$$. However, they also thought it would have been smart to tell people that structures (value types) are not that different from classes (reference types), because both can implement interfaces. Of course, this is not true. There is a run-time boxing when you cast a structure to an interface, but of course, that detail can be hidden. Or maybe not. One of my customers found himself stuck on a code that, largely simplified, could look like this:
In the real code, Change() was not static, and it was called sometimes passing instances of classes, and sometimes instances of structures. The structure was written before the need for implementing the interface was discovered. But isn't that what inheritance and polymorphism is about? :-)
Of course, the code writes "23", not "24", because is a boxed structure that gets modified, not the original structure, that is not implementing the interface at all: the boxing class is! If you call s.Set( 24 ) directly from Main(), instead, s is changed, because no polymorphism is involved in this case.
Unfortunately, this tiny little detail cannot be safely hidden. It should be clearly written on basic documentation and taught on introductory courses on C#. Otherwise, programmers will shoot themselves in the foot (although with a small caliber :-).
Hopefully, most C# programmers won't use a structure anyway, and some of them will therefore avoid this bug by sheer luck :-).
Unfortunately, language designers often want to hide to the ignorant programmers (that is, the rest of us) some "details" that they deem to hard to understand or master, or too boring to deal with continuously, and so on. They are often well-intentioned (although a little patronizing :-), but the result is often a huge mess.
Consider COM: it started as an easy way to write language-independent (sort of) macro-components in C++. Initially, there was no notion of a threading model: you should have been careful, on the producer and consumer side. That was it.
When VB came along with its support for COM, they decided that the programmer was too stupid to master concurrency (not to mention the thread affinity of old ODBC drivers and the like) and they invented the threading models. That was a well-intentioned bad idea :-), because even today, just a minority of programmers really understand the subtleties of COM threading models ( quick check: can you really explain the difference between choosing "free threading" or "both" in the ATL wizard? :-).
Now, when C# and .NET came along, someone must have decided that exposing the difference between value types and reference types all the time would have been bad. Indeed, I like the idea of implicit boxing, as explicit boxing a-la Java is a pain in the @$$. However, they also thought it would have been smart to tell people that structures (value types) are not that different from classes (reference types), because both can implement interfaces. Of course, this is not true. There is a run-time boxing when you cast a structure to an interface, but of course, that detail can be hidden. Or maybe not. One of my customers found himself stuck on a code that, largely simplified, could look like this:
interface M
{
void Set( int x ) ;
}
struct S : M
{
public S( int x ) { v = x ; }
public int Get() { return v ; }
public void Set( int x ) { v = x ; }
private int v ;
}
class Test
{
public static void Change( M m )
{
m.Set( 24 ) ;
}
static void Main()
{
S s = new S( 23 ) ;
Change( s ) ;
System.Console.WriteLine( s.Get().ToString() ) ;
}
}
In the real code, Change() was not static, and it was called sometimes passing instances of classes, and sometimes instances of structures. The structure was written before the need for implementing the interface was discovered. But isn't that what inheritance and polymorphism is about? :-)
Of course, the code writes "23", not "24", because is a boxed structure that gets modified, not the original structure, that is not implementing the interface at all: the boxing class is! If you call s.Set( 24 ) directly from Main(), instead, s is changed, because no polymorphism is involved in this case.
Unfortunately, this tiny little detail cannot be safely hidden. It should be clearly written on basic documentation and taught on introductory courses on C#. Otherwise, programmers will shoot themselves in the foot (although with a small caliber :-).
Hopefully, most C# programmers won't use a structure anyway, and some of them will therefore avoid this bug by sheer luck :-).
Sunday, October 16, 2005
Berries and mushrooms
Today was a nice sunny day here in Liguria, and I spared a couple of hours in the morning for a short run. Nature is not as impressive as in spring, but there are hidden treasures everywhere, especially berries of all kinds. I've also seen mushrooms I hadn't seen in (at least) 20 years :-). They looked like a Ramaria Aurea but I'm definitely not an expert...
Note to myself :-) : weather forecast notwithstanding, if I'll catch another sunny day anytime soon, I'll bring a digital camera, walk instead of running, and take a few pictures...
Note to myself :-) : weather forecast notwithstanding, if I'll catch another sunny day anytime soon, I'll bring a digital camera, walk instead of running, and take a few pictures...
Builder [pattern] as an option
The decision between using a Builder (basically exploring a DOM and creating different classes as needed) or using language-specific features (like serialization attributes or the SOAP serializer in .NET) is easy to take in some contexts, and harder in others. Usually, it's hard when it's too early to decide. While running today :-), I realized that this is a perfect example where you can cheaply "buy" a modularization option and postpone the decision for a while. Just add a Builder class, it's very cheap. If you need a real builder, you'll have the right hook already there. If you can go with language-specific features, the Builder will end up being very simple, like creating the concrete serializer and little more. For more on options, see my previous posts, Real Options and Software Design and Kicking reuse in the A$$.
Labels: design, real options
Friday, October 14, 2005
Full throttle
Once in a while I scrap the exercises for my design courses and create new ones from scratch. It's not just to avoid boredom :-). It's to make the course itself more realistic: I'll have to confront questions I've never heard, discuss solutions I've never seen, make mistakes I never made :-), and that's closer to the real life of a software designer than going over a problem you know from each and every angle. I often encourage people to bring their own problems (for the same reasons) but I still come with a set of exercises, selected for their educational power.
I usually work out a reasonable solution - is doesn't have to be perfect: it has to be sensible, and to provide some room for discussion and for improvements. Designers (or future designers) need an highly developed critical sense.
Each and every choice has some good and some bad consequences: we must be aware of both, and choose the best trade/off between alternative designs. Of course, this is true in most areas of life as well. Nothing is just good. Especially in high quantity.
While sketching a solution to a new exercise for my design patterns course, or more exactly while thinking about the downside of a choice, I got one of those totally unrelated thoughts. Or maybe not so unrelated :-). It was about something I read time ago in "Extreme Programming Explained - Embrace Change" from Kent Beck: "When I first articulated XP, I had the mental image of knobs on a control board. Each knob was a practice that from experience I knew worked well. I would turn all the knobs up to 10 and see what happened. I was a little surprised to find that the whole package of practices was stable, predictable, and flexible". So flawless? Full throttle, and no downside? How come I can't believe it? :-))
I usually work out a reasonable solution - is doesn't have to be perfect: it has to be sensible, and to provide some room for discussion and for improvements. Designers (or future designers) need an highly developed critical sense.
Each and every choice has some good and some bad consequences: we must be aware of both, and choose the best trade/off between alternative designs. Of course, this is true in most areas of life as well. Nothing is just good. Especially in high quantity.
While sketching a solution to a new exercise for my design patterns course, or more exactly while thinking about the downside of a choice, I got one of those totally unrelated thoughts. Or maybe not so unrelated :-). It was about something I read time ago in "Extreme Programming Explained - Embrace Change" from Kent Beck: "When I first articulated XP, I had the mental image of knobs on a control board. Each knob was a practice that from experience I knew worked well. I would turn all the knobs up to 10 and see what happened. I was a little surprised to find that the whole package of practices was stable, predictable, and flexible". So flawless? Full throttle, and no downside? How come I can't believe it? :-))
Monday, October 10, 2005
Curiously Recurring Template in C#? No way...
The Curiously Recurring Template Pattern, first presented by James Coplien in the homonymous paper in C++ Report, Feb. 1995, and independently discovered by several other programmers (including myself :-) is an interesting use of C++ Templates. It is now widely used in commercial libraries (e.g. ATL), open source (e.g. Boost) and basically whenever a clever use of templates is involved (see, for instance, my Multiple Dispatch: a new approach using templates and RTTI).
Basically, it involves a class that is derived by a template instantiated on the derived class itself. Here is a simple example of factoring out into a base class a common implementation of Clone for all the derived classes:
If you're unfamiliar with it, you may want to read it twice :-).
While playing a little with generics in .NET 2.0, I tried something like that in C#. In the simplest incarnation, that would be:
As you may guess by now, it didn't work. You get an error message like "Cannot convert type Base< T > to T". This message alone tells you a lot about the compile-time model of generics in C# compared with the compile-time model of templates in C++.
Note for .NET fans :-) : of course, Clone() in .NET does not need the CRTP. In fact, in more than a few cases, the CRTP can be successfully substituted with a solution based on reflection (but not viceversa, although reflection is obviously slower). Still, the CRTP is a valuable code factoring technique, which is not available in .NET.
For More on the CRTP, see also this wiki. Coplien's article has also been reprinted in Stanley B. Lippman, editor, "C++ Gems", Cambridge University Press & Sigs Books, 1996. Old stuff, but still valuable; if you missed it, try to get a copy...
Basically, it involves a class that is derived by a template instantiated on the derived class itself. Here is a simple example of factoring out into a base class a common implementation of Clone for all the derived classes:
template< class T > class Base
{
public :
T* Clone() const
{
return new T( static_cast< const T& >( *this ) ) ;
}
} ;
class A : public Base< A >
{
// I have a clone for free, based on
// the copy constructor of A
} ;
If you're unfamiliar with it, you may want to read it twice :-).
While playing a little with generics in .NET 2.0, I tried something like that in C#. In the simplest incarnation, that would be:
class Base< T >
{
void g()
{
((T)(this)).f() ;
}
}
class Derived : Base< Derived >
{
void f() { }
}
As you may guess by now, it didn't work. You get an error message like "Cannot convert type Base< T > to T". This message alone tells you a lot about the compile-time model of generics in C# compared with the compile-time model of templates in C++.
Note for .NET fans :-) : of course, Clone() in .NET does not need the CRTP. In fact, in more than a few cases, the CRTP can be successfully substituted with a solution based on reflection (but not viceversa, although reflection is obviously slower). Still, the CRTP is a valuable code factoring technique, which is not available in .NET.
For More on the CRTP, see also this wiki. Coplien's article has also been reprinted in Stanley B. Lippman, editor, "C++ Gems", Cambridge University Press & Sigs Books, 1996. Old stuff, but still valuable; if you missed it, try to get a copy...
Sunday, October 09, 2005
Simple ideas on measuring the business value of a feature
In an earlier comment, I've mentioned the need to make a clear case for the business value of features and design choices. Since features, and in general user-level choices, are easier to discuss with management than lower-level design choices, they could make for a good training :-) about thinking at the edge between software and business.
Here is an easy to read article offering some simple, yet practical suggestions: Identifying the Business Value of What We Do. On the same website, you'll also find some nice papers on usability, and a few more dealing with business issues and software design.
Here is an easy to read article offering some simple, yet practical suggestions: Identifying the Business Value of What We Do. On the same website, you'll also find some nice papers on usability, and a few more dealing with business issues and software design.
Thursday, October 06, 2005
Teaching exception handling in C++
I'm teaching my course on exception handling in C++ at a VoIP company, and that brought some reflections to my mind. Looking back, in the beginning exception handling was a mysterious concept for most programmers: Tom Cargill played an essential role by pointing out, in his now historical "Exception Handling: a False Sense of Security"(C++ Report, November/December 1994), how little we knew at the time about the subject.
More than 10 years later, we definitely know more. Scott Meyers and Herb Sutter have published papers and books that pretty much summarize most of what we know about the mechanic of exception safety. What seems to be missing is a good paper documenting a design approach to exception safety, and in particular, how a family of smart pointers should (or must :-) be defined and used right at the design level, from UML models up. I gave some hints in my "UML 2 Manuale di Stile", but that's far from being a comprehensive reference on the subject (it won't be the right place, anyway).
What is curious is that this overdue paper would have no natural place to appear (in print). Years ago, the C++ Report or the JOOP would have been two perfect journals for such an article. Today, we only have the C++ User's Journal left, and they don't publish articles on "methods". They do have columns talking about methods (somehow), but a column, by definition, is not open to contribution. Sure, there is always the web, or some conference proceedings, but in both cases, the visibility of the paper may not justify the effort spent writing [a good] one. There seems to be no mainstream publication devoted to good design techniques, from class/method level to architectural level. I've recently seen sensible papers featured in technology-centric journals, but that's more the exception :-) than the rule. Interesting papers are published on IEEE periodicals once in a while, but I won't consider that as "mainstream". I guess there is no economy of scale, both on the reader's and on the author's side (excluding the ever-abundant theoretical papers). Reasons and implications of that form a huge, self-sustaining :-) cause/effect graph which would be so fun to draw...
More than 10 years later, we definitely know more. Scott Meyers and Herb Sutter have published papers and books that pretty much summarize most of what we know about the mechanic of exception safety. What seems to be missing is a good paper documenting a design approach to exception safety, and in particular, how a family of smart pointers should (or must :-) be defined and used right at the design level, from UML models up. I gave some hints in my "UML 2 Manuale di Stile", but that's far from being a comprehensive reference on the subject (it won't be the right place, anyway).
What is curious is that this overdue paper would have no natural place to appear (in print). Years ago, the C++ Report or the JOOP would have been two perfect journals for such an article. Today, we only have the C++ User's Journal left, and they don't publish articles on "methods". They do have columns talking about methods (somehow), but a column, by definition, is not open to contribution. Sure, there is always the web, or some conference proceedings, but in both cases, the visibility of the paper may not justify the effort spent writing [a good] one. There seems to be no mainstream publication devoted to good design techniques, from class/method level to architectural level. I've recently seen sensible papers featured in technology-centric journals, but that's more the exception :-) than the rule. Interesting papers are published on IEEE periodicals once in a while, but I won't consider that as "mainstream". I guess there is no economy of scale, both on the reader's and on the author's side (excluding the ever-abundant theoretical papers). Reasons and implications of that form a huge, self-sustaining :-) cause/effect graph which would be so fun to draw...
Monday, October 03, 2005
Blogging as Destructuring
I've been an author for several years now, with more than 100 papers published in trade and academic journals. I've also published a "traditional" book (my "C++ Manuale di Stile", in Italian) and I'm slowly working on my free book "UML 2 Manuale di Stile" (again, in Italian). For a few years I also published a newsletter on C++ ("C++ Informer"). In the last few months, I've also been "publishing" here in the blog. There is a tremendous difference between the two experiences, and blogging is the ultimate destructuring of writing. There is no expectation (on the author's and readers' side) of thoroughness, completeness, even relevance. This allows a much faster flow of ideas. If a blog is irrelevant, people will stop visit. That's it, clean and simple.
Looking back, I see that over the years I've accumulated tons of ideas, drafts, diagrams, etc that never took shape as an article (or book). We have natural expectations about printed articles, that requires a huge overstructuring of the presented material and therefore a huge amount of collateral work. For instance, I've dozen of examples of bad user interaction in the real world, similar to what I discussed in Natural Form Filler. However, the effort required to bring this (possibly interesting) material to a publication-grade level is just too big, and possibly unjustified.
Things get worse if you plan to submit your works to top-notch publications. If you never had this experience, I can highly recommend reading The long and winding road: getting papers published in top journals by John Mingers. I hope you'll see the inherent inefficiency of a process born out of good intentions (quality assurance) but oh so obsolete. This inefficiency results in long delays before concepts are disseminated, and also in selective prevention of radically new concepts being disseminated. Of course, people are starting to notice. An interesting article in Communications of ACM, August 2005, proposed a different approach to sharing research results, similar to an open source project ("Sharing Research in the 21st Century: Borrowing a Page from Open Source Software", by Donald E. Hardaway).
I won't hold my breath :-). So, while I'm not giving up about "traditional" publishing, I guess for a (long) while I'll use the blog as my favorite media, and enjoy the freedom of destructuring :-).
Looking back, I see that over the years I've accumulated tons of ideas, drafts, diagrams, etc that never took shape as an article (or book). We have natural expectations about printed articles, that requires a huge overstructuring of the presented material and therefore a huge amount of collateral work. For instance, I've dozen of examples of bad user interaction in the real world, similar to what I discussed in Natural Form Filler. However, the effort required to bring this (possibly interesting) material to a publication-grade level is just too big, and possibly unjustified.
Things get worse if you plan to submit your works to top-notch publications. If you never had this experience, I can highly recommend reading The long and winding road: getting papers published in top journals by John Mingers. I hope you'll see the inherent inefficiency of a process born out of good intentions (quality assurance) but oh so obsolete. This inefficiency results in long delays before concepts are disseminated, and also in selective prevention of radically new concepts being disseminated. Of course, people are starting to notice. An interesting article in Communications of ACM, August 2005, proposed a different approach to sharing research results, similar to an open source project ("Sharing Research in the 21st Century: Borrowing a Page from Open Source Software", by Donald E. Hardaway).
I won't hold my breath :-). So, while I'm not giving up about "traditional" publishing, I guess for a (long) while I'll use the blog as my favorite media, and enjoy the freedom of destructuring :-).
Sunday, October 02, 2005
Atom Newsfeeds
I have enabled site feeding on my blog, so you can now subscribe to it from any atom-enabled newsreader. I like RSSOwl, but you can find a list of newsreaders at AtomEnabled.org.
Just point your newsreader to my atom file at http://www.eptacom.net/feed/atom.xml, it should work like a snap :-).
Note: I'm publishing only a "short" version on the newsfeeding channel, so if you want the full story, come here or click on the full article link on your newsreader...
Just point your newsreader to my atom file at http://www.eptacom.net/feed/atom.xml, it should work like a snap :-).
Note: I'm publishing only a "short" version on the newsfeeding channel, so if you want the full story, come here or click on the full article link on your newsreader...
Quote of the day
There is a quote from T. S. Eliot that is somewhat popular among computer scientists and software engineers. You can find it appearing with a certain frequency on papers, conference proceedings and websites. It goes like this: "Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?".
The bright side of the story is that the complete quote would be this: "Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?". For one reason or another, the first portion does not appeal so much to the software guys :-)).
The bright side of the story is that the complete quote would be this: "Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?". For one reason or another, the first portion does not appeal so much to the software guys :-)).
Saturday, October 01, 2005
UML 2 Manuale di Stile
Nuovo rilascio del mio UML 2 Manuale di Stile. Ho aggiunto circa 8 pagine relative ai pseudostati di shallow e deep history. Prossimamente, aggiungero' un paragrafo sugli eventi differiti.


