Wednesday, March 15, 2006

Jargon Clash

=====================
JARGON CLASH
(C) 2006 Thomas Jacob
=====================

Introduction
------------------
The construction of a system is a progression from one stage of clarity to the next.

1. We start with hazy requirements - It's a three-line requirement doc!
2. We try to gather more details - Now, what could this be?
3. We feel we have achieved enough clarity - Oh, that's what he meant!
4. We start to implement the system. - What could go wrong? It's clear and easy.
5. ...and yet, in the final count, the system fails to match the user's expectations/requirements.

Often, the problem lies in the inaccurate representation of facts and requirements. In this article, we explore one of the causes for this.

The Quest For The Holy Grail
-----------------------------------------
The importance of capturing the requirements correctly (as a "Requirement-Model") cannot be overemphasized. After all, the system is built to satisfy the requirements of the users. If we understand the requirements incorrectly, we have an inaccurate Requirement-Model, and the system (which is based on it) will not, cannot be successful.

A major obstacle in our quest for the perfect Requirement-Model is the lack of in-depth knowledge about the field in which the system will be used. This is unavoidable as one cannot be an expert in everything. And that's just as well because what's required of a maker of a paintbrush is that he should be able to make the paintbrush well, not that he should be able to paint well! There is no need for the designer of a CD-player to be a composer as well (though of course, it helps the cause if he "understands" music). It's horse for courses and that's why you have been chosen to develop the system and not the user.

Drinking From The Poisoned Cup!
-------------------------------------------
We need to close the gap in our understanding of the requirements (The system needs to be built, right?) by asking the users for further details. The users might explain things in a seemingly familiar language, but the words could mean something entirely different than the meaning you got. Beware of Jargon-Clash! The user and you, both are experts, and experts, almost as if by definition, tend to use jargon. What you hear and get may not be what they mean!

A trivial, stupid(?) and impossible(?) example: You are implementing a distributed system for a retailing chain. The user says that the client needs to retain the bill. You could very well take thisthis down and, justifiably, note that the bill information needs to be stored at the client-side and go "Wow! Finally...I get to do distributed databases!". Probably all the user would have meant was the the customer (client for the user) needed to be given a printed bill!

Another, closer-to-reality example. The term "ATM" would mean "Automated Teller Machine" (the cash-dispensing type) to the "normal" user but to a networking professional, ATM would mean "Asynchronous Transfer Mode", a technology for networking. What then would an ATM network be? And couldn't there be ATM networks which use ATM technology for the network? Think about the very-many ambiguous conversations possible!

The Jargon-Clash isn't limited to the "unsavvy user, savvy developer" system-construction scenario either. In fact, the more similar the jargon of the user and the jargon of the developer, the higher the probability and impact of Jargon-Clash is. What's worse is that the Jargon-Clash will be less obvious. The effects may become evident only at an advanced stage of the project.
Example: Computer networking and telecom are closely related, especially in this age of Internet telephony. But the term TCP, for a network programmer, would refer to the TCP/IP communication protocol and to the telecom profession would mean a Trunk Control Program.

It also helps if the user too could be made aware of Jargon-Clash. Jargon-Clash could lead to destruction of mutual respect between the user and the developer. But surely, everybody knows what pinging is! How can he be so stupid? The situation now would be, as Strother Martin's character wryly observed in the film Cool Hand Luke, "What we've got here is failure to communicate." Every concern, every requirement is not conveyed and the accuracy of the Requirement-Model is affected.

For want of a nail, a kingdom can be lost and for lack of an accurate Requirement-Model, a system will be doomed to fail.

Poison Is The Cure
-------------------------
Pass everything the user says through the filter of Jargon-Clash awareness.

Try to agree upon a common vocabulary and clearly define each term of relevance. Make a glossary or a project-specific dictionary. It is very important to disambiguate, not only for the accurate elicitation of requirements from user, but also for the ease of implementation.

Construct new terms (a new jargon) if needed, if doing so would -
a) make things less ambiguous, and
b) improve the effectiveness of communication.
Alternate styles of capitalization or the merging of words would suffice in many cases to remind the reader/user that we are using the term in a special meaning.

It bugs readers no end to see repeating groups of words. Think "documentation of user-requirements" instead of Requirement-Model or "the problems caused by the common terms in the user's and developer's jargon" instead of Jargon-Clash. Abbreviate effectively, but do not make things too abstruse.

Validate your Requirement-Model with the user if possible, and then, using the mutually-agreed-upon non-ambiguous vocabulary. If properly validated, the Requirement-Model would simplify the onerous task of system-development considerably.

Summary
------------
Ambiguous terms corrupt the Requirement-Model.
Equivocal Requirement Model = A Failed System.
The corruption propagates and gets magnified.
The developed system turns out to be different from what is required.
Users ditch the system. Wasted time, wasted effort.

Beware of Jargon-Clash.
Disambiguate, at any cost.
Even by inventing a new jargon!

- Thomas Jacob

=================================================================

Saturday, March 04, 2006

Advice for language designers

I strongly felt then, as I still do, that there is no one right way of writing every program, and a language designer has no business trying to force programmers to use a particular style. - Stroustrup

dynamic_cast prerequisite

A dynamic cast is performed run-time. A prerequisite for using the dynamic cast operator is the existence of at least one virtual member function in the base class.

Tuesday, February 28, 2006

On The Naming Away - I

The importance of the names that we give variables and functions cannot be overemphasized. I would even go so far as to say that, at times, proper naming is more important than the functionality being coded itself! Sadly, in the mad rush to get things working, this aspect of coding is often neglected. :-(

Remember: code is also for reading!

Sunday, February 19, 2006

Template Friend Functions

code snippet picked up from the net. don't remember where.


#include
using namespace std;
template
class SomeClass{
private:
T member;
public:
...
friend ostream& operator<<(ostream &,SomeClass &);
};

template
ostream& operator<<(ostream &os, const SomeClass&some){
os<<"( " << some.member <<") ";
return os;
}

int main(int argc, char* argv[])
{
SomeClass sc(5);
cout << sc; // Problem????
return 0;
}


It reported that operator << was not found.

The problem is that in the class definition, a friend was declared as a function, not a template function. To make the code link properly, the friend declaration should be changed to:

friend ostream& operator<< <>(ostream &,SomeClass &);


Just another little C++ twist.

Thursday, February 02, 2006

Attack Of The Clones

Presque vu: is a French term which means "almost seen". It is the feeling of very nearly, but not quite, remembering something.

Here are three operating system projects that attempt to recreate or provide the look-and-feel and user-experience of other operating systems. They are driven by fervent nostalgia, but could they, will they, ever be "even better than the real thing?

1. ReactOS - Aims to provide an implementation of a Windows® compatible OS
ReactOS homepage

2. Haiku - Aims at the re-creation of the Be Operating System.
Haiku OS homepage"

3. CoLinux - port of the Linux kernel that allows it to run alongside another operating system on a computer. Run Linux on Windows® 2000/XP.
Cooperative Linux Homepage

Monday, January 23, 2006

Indirection Is Flexibility

Indirection (n)
1. "indirect procedure or action".
2. "deceitful action that is not straightforward"

Indirection in system design is when instead of explicitly specifying how exactly something is done, we delegate the responsibility to another person/entity. We buy belts that are looser than needed, just in case we get fatter, don't we?

Let's say somebody who's new in town asks us what he should do to start a bank account. We could -
a) tell him to go to the bank and meet the manager there.
b) give him the exact list of required documents, the order in which to submit them and to whom.

Take into account the always-changing laws and the idosyncrasies of different banks, and the advantages of the first approach are self-evident! That's indirection for you. We would of course give him the address of the bank and possibly also the title of the official (manager, if he is a life-newbie as well).

Indirection helps us surmount change. In programming, we achieve indirection through the use of pointers and references instead of actual objects. Indirection is closely related to the concept of abstraction.

OO perspective: Instead of specifying the exact type of the implementor, we just mention that it will be of a certain type,say, Base . This is the foundation on which most design patterns are constructed. We can later on replace this reference with a more specialized object (derived from Base), if needed, to provide extra/changed functionality.

Other examples:
The use of virtual machines like .NET's CLR or Java's JVM instead of the actual processor gives us portability as a useful side-effect.
The use of pointers in C/C++ gives us space-efficiency.

There ain't no such thing as a free lunch. Indirection gives us flexibility at the expense of performance. No matter how trivial the cost is, there is a price to be paid. You can't have your cake and eat it too!

Sunday, January 08, 2006

OS Development Resources

A new year's present for the wannabe OS developer

http://www.osdever.net/tutorials.php?cat=0&sort=1

May you not fail for the lack of guidance!

Wednesday, December 07, 2005

T&L - Not Made For Each Other?

---------------------------------
THREADS AND LIBRARIES
NOT MADE FOR EACH OTHER?
---------------------------------

1 INTRODUCTION

Threading libraries hide very little of the complexity involved in the use of threads. Often, the focus and the major obstacles in implementing a multithreaded system are the low-level details of threading, rather than the problems that the system is designed to solve.

Objects can be said to model reality, thereby providing good abstraction. However, a crucial part of reality that is not represented adequately in an object is a sense of time. Objects exist in time and space, and interact with other objects; they have "life". A mechanism for intuitively expressing such Live Objects (or Active Objects), where an object has its own thread, is missing from the threading libraries in (libraries of) object-oriented languages today.
Spatial representation OK.
Temporal representation, not OK.
2 CURRENT THREADING MECHANISMS

Presently to use threads, we create a thread and give it sections of code (from the object) for it to do. For example,

threadHandle=CreateThread(StuffToDo , OS/LibraryParameters)

is how threads of control are created from the program. The code (StuffToDo) is then executed in the newly created thread.

2.1 Observations

In the present library implementations,

2a Threads use objects.
The thread executes a function, possibly a function or method of an object. In the example, StuffToDo could be the method of an object.

2b Threads are to functions what objects are to classes.
Or, threads are objects. The thread object instantiates a function, brings into execution-space so to say, executing it. The implementation forces the thread to become a first-class "object" in the program-space. It has a handle, threadHandle, that can be used to refer to it.

2c Threads are almost equivalent to operating system threads.
Most of what can be done with an operating system thread can be done with library threads also - one can suspend a thread, resume it, abort it etc

3 'OBJECT'IONS - CRITIQUE

In the real world, entities use their time and their resources to do things. A thread can be viewed as a flow of time for practical purposes. In the library-model, threads use objects (2a) whereas in reality, objects use threads. This unnatural modeling contributes to the difficulties of conceptualizing and implementing threaded systems.

It should be "Objects use threads",
not "Threads use objects".

An object oriented program/system is an exchange of messages between objects resulting in side-effects useful towards the solution of the problem at hand. Thread objects (2b) are only an implementation mechanism, a way of calling a function; they do not help to manage complexity. Instead, thread object interactions add complexity and intrude on the main logic of the program.
In the scenario of single-threaded program development, come to think of it, the programmer plays the role of the thread object during coding- deciding which functions to call and in what order. Sadly though, this does not scale - which is why multithreaded programs are so challengingly complex.
Why have thread objects at all in programs? Threads are, very much, operating system entities (2c) . If we have the thread object in the program, it is only natural that they have methods similar to the real-world (albeit on the OS-side) entities that they model, with some high-level constructs thrown in for good measure. If we have thread objects, the complexity of threading cannot be hidden from the programmer.
For operating systems, threads are expensive to manage. The objection to live objects that is raised all too often is: "What! If I have a 1000 live objects, it would mean 1000 threads too? You must be out of your mind..." This mental block must be removed. The programming language back-end (the popular idiom of the runtime) can possibly be adapted to meet the external implementation constraints.
Hide the complexity of threads from the programmer, effectively.
4 OOTOPIA
Ideally, after the definition of live objects, one would be able to program like a classroom interaction like this:
void main()
{
TeacherLiveObject theProf;
StudentLiveObject theStudents[30];
}
That would be it?
5 CONCLUSION

A LOOP (Live Object Oriented Programming) language is the need of the hour. Such a language would help people to take their minds off low-level threading details and focus on more domain-relevant issues at hand, enabling the construction of more useful programs.

- Thomas Jay Cubb


External links
1 The Free Lunch Is Over
2 Software and the Concurrency Revolution
3 Discussion on Active Objects In Python
4 IBM Research- The X10 Programming Language - A LOOP language?
5 Polyphonic C# in Cw - Another LOOP language?

Tuesday, December 06, 2005

Cline's Commandments

* A class Fred's assignment operator should return *this as a Fred& (allows
chaining of assignments)
* A class with any virtual[20] functions ought to have a virtual
destructor[20.4]
* A class with any of {destructor, assignment operator, copy constructor}
generally needs all 3
* A class Fred's copy constructor and assignment operator should have const in
the parameter: respectively Fred::Fred(const Fred&) and
Fred& Fred::operator= (const Fred&)
* When initializing an object's member objects in the constructor, always use
initialization lists rather than assignment. The performance difference for
user-defined classes can be substantial (3x!)
* Assignment operators should make sure that self assignment[12.1] does
nothing, otherwise you may have a disaster[12.2]. In some cases, this may
require you to add an explicit test to your assignment operators[12.3].
* In classes that define both += and +, a += b and a = a + b should generally
do the same thing; ditto for the other identities of built-in types (e.g.,
a += 1 and ++a; p[i] and *(p+i); etc). This can be enforced by writing the
binary operations using the op= forms. E.g.,

Fred operator+ (const Fred& a, const Fred& b)
{
Fred ans = a;
ans += b;
return ans;
}


This way the "constructive" binary operators don't even need to be
friends[14]. But it is sometimes possible to more efficiently implement common
operations (e.g., if class Fred is actually String, and += has to
reallocate/copy string memory, it may be better to know the eventual length
from the beginning).

Sunday, December 04, 2005

ISO C++ updates

A static const integer member is the one instance in C++ in which a class member can be initialized explicitly within the class definition, thereby making the value available to other constructs within the class, such as the dimension size of m_buffer. Without this construct, the use of an enumerator as a symbolic constant was a common workaround.

There is now covariant return type support in the definition of virtual functions. This is great news for those who write class hierarchies.

There is support for the implicit return of 0 within main.

Tuesday, November 29, 2005

Heart For The GNU

This short poem tries to encapsulate some Linux history.

Linus Torvalds wanted to modify Andrew Tenenbaum's MINIX operating system initially. But Tanenbaum did not give him permission, so he set about writing his own operating system. This became the kernel for the GNU project which aimed at making a free operating system.

--------------------------------
A HEART FOR THE GNU
--------------------------------
Tanenbaum forbade,
Linus obeyed.
Fiat Linux!
Freedom redux.

- Thomas Jay Cubb


Notes
--------
1. "Fiat Lux" is a Latin phrase meaning "let there be light" from the Bible's Genesis book which relates God's creation of the world. Linus, the Creator! So, Fiat Linux.
2. redux = Brought back. The GNU OS project was losing steam and face, for the lack of a suitable kernel for its operating system. The Linux kernel, so to say, resurrected it. (GNU/Linux)


You may also be interested in reading Punnix.