A site devoted to discussing techniques that promote quality and ethical practices in software development.

Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, May 14, 2015

My experience in using one2free prepaid Mobile Broadband SIM in Hong Kong

I am a regular visitor to Hong Kong and in every visit, I purchase a prepaid mobile broadband data SIM for my Huawei pocket modem to provide Internet service to me. I am no stranger to this kind of SIM as I have used in the past various types of 3HK Data SIM. So after reading so many glowing remarks about the one2free's prepaid mobile broadband SIM, I have decided to give it a test ride this time.

I did some preliminary investigation prior to the visit via their e-mail customer service which I may say is rather responsive by comparison. It would be nicer if they have 3HK's online chat service.

On the whole, I am rather pleased with the performance, the cost, the responsiveness of the customer service which I had to use quite a lot, as you will see, during my stay. Unfortunately, their responsiveness is tarnished somewhat by their answers which clearly indicate that they are let down by their organisation.

Now, with the good bits out of the way, let's go through the bad bits.

Foremost is their web site which is devoid of any useful and helpful information. It would be more helpful if their web site provides some form of instructions in using their services. Such as what happen if you buy the $100 starter kit, what rate will you be charged at. What about the steps to buy the 30-Day Pass with 3GB quota for someone what has not used your product before? What happen when one uses up the quota but still within the 30 days? Will the connection speed be shaped?

In my case, I want to use the 3GB 30-day pass, which according to the published information will cost me HK$148.00. To subscribe to that, one needs to load the prepaid SIM with at least (preferably more) that that amount. At the shop where I purchased the kit, they did not have $50 top up voucher instead they only had $100 voucher which means my SIM card is loaded with $200 and after paying for the 30-Day pass, it has a balance of $52.00.

No where in their web site explaining this and what happens to that balance. For those wanting to go down this path, here is the treatment of the balance.

The 30-Day pass expires after 30 days from the day of subscription. CSL will immediately deduced that amount from your card on subscription. Hence you must load your card up with sufficient amount before you can punch in the code to select the day pass. The amount remaining can be use for other purposes such as making calls or to contribute towards next day pass purchase. It does not expire until 6 months after the activation or from your last top up. In other words, your prepaid SIM card is valid for 6 months as long as there is sufficient fund to pay for the monthly government charges, which is HK$2.

Unless you do not have other SIM to make voice call, this SIM charges (HK$0.3/min) 3 times as much as other CSL SIM ($0.1/min).

The next area of great disappointment is how to monitor the data usage. Their web site for the prepaid starter kit contains wrong and misleading information.

While that site is for the Prepaid Mobile Broadband SIM, the login button is not intended for Prepaid mobile and I only found this out after the event.

This web site expects the user to possess certain degree of psychic to realise that. I was misled by this page and unsuccessfully to get a password or to reset it by following the online link. Out of desperation, I inserted the data SIM into a mobile phone and used the *777 code to successfully reset the 6-digit password for my SIM. The system acknowledges the request and echoes back the password (very security conscious).

Next, armed with my SIM's mobile number and the password, I pressed the login button on that web page. Rather than telling me that my SIM cannot use 'My Account' to manage my usage, it throws a Java Exception message:
type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.IllegalStateException
 org.apache.coyote.tomcat5.CoyoteResponseFacade.sendRedirect(CoyoteResponseFacade.java:418)
 LoginRedirect.doPost(Unknown Source)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:767)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:860)
 sun.reflect.GeneratedMethodAccessor57.invoke(Unknown Source)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:585)
 org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:249)
 java.security.AccessController.doPrivileged(Native Method)
 javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
 org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:282)
 org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:165)

note The full stack trace of the root cause is available in the Sun-Java-System/Application-Server logs.

Nice? Have they ever tested their program? Why doesn't the web page inform their user that the login page is not for Prepaid user? Surely, they have all the information to tell if the caller's SIM is a prepaid or not.

I raised this issue with the online support as well as visiting one of their customer service centres and was then told that that login button on the web page and "My Account" facility are not for Prepaid users. Surely their web designer can put that few words into their page to warn their user and even better, their program tests and traps that kind of exception and to inform their users in a more meaningful manner. It is not a big ask isn't it. More disturbingly, if that facility is not for prepaid user, why does *777 allows a number belonging to a prepaid SIM to reset password? So amateurish!

So after the visit, I discovered that as a NextG-Prepaid user, I should use this URL http://www.one2free.com/nextg-prepaid while connecting to the CSL using the one2free SIM. Using this URL, I have managed for the next 3 days to make a daily enquiry of my usage.


On the 4th day, when I used that URL, I was confronted with this web page:

Notice that the left hand pane tells me that this is a "My Account" facility, the very facility that I was told that it was not for me.

Not deterred and with a sense of adventure, I pressed the login link which sent me to https://prepaid.hkcsl.com/login with the following login page

The login page asks for the mobile number of the SIM and a password, which I duly use the one that I used the *777 code to reset. The system accepts my inputs and provides me access to my SIM's data. The data usage can be retrieved by pressing the "Promotional Bonus Details" link.


Notice this is a different web page as compared to the previous one via the NextG-Prepaid link.

I sought the customer service for an explanation of how I could access "My Account" when they told me that it is not for me to no avail. We ended up going around and around in circle. The customer service refuses to acknowledge that the URL https://prepaid.hkcsl.com/login is right for me despite being pointed out that the URL containing the word 'prepaid' to indicate that it is for prepaid users.

Even more interestingly is that I can access my prepaid SIM card detail using this URL without having to use a connection provided by CSL SIM while I need to use the one2free SIM in order to use the http://www.one2free.com/nextg-prepaid regardless successful or not. As an experiment, I have just connected to this https://prepaid.hkcsl.com/login some thousands miles away from Hong Kong.

After discovering that I can use this URL to monitor my data usage, I continue to use it ignoring any contradictory comments from the customer service. Incidentally this URL is not disclosed on any of the CSL web pages. It seems that there is a communication problem within the CSL on this issue.

Whatever it is, it is CSL's problem and they need to deal with it. I have supplied all the information, such as SIM card number, mobile number, and modem model. They need to improve their web site to make it more useful and helpful. Don't just throw figures and data on it. Test it with someone who is not a user of your system or product.

Teach your front line support personnel to slow down and take time to explain the various facets of your products. I know you know your products very well but your potential customers DON'T.

Test your web site with any non-sensible data and don't let your Java exception message leak out to the users. That is not an acceptable way to tell your user that they have entered something wrong.

To date, I still have not been offered a logical explanation why the link http://www.one2free.com/nextg-prepaid, I was instructed by the customer service to use, failed after 3 days. And that why I should not use https://prepaid.hkcsl.com/login which works but the customer service next acknowledges that I should use that.

Thankfully, I have a wonderful Internet service and despite all the above mentioned issues, it is still cheaper than 3HK's offering and I still will recommend it to other travelers. Just be prepared for some rough edges.

Thursday, June 30, 2011

There is no dangerous language only dangerous programmers

It seems the data and comments presented in "Software Failures, follies and fallacies" by Les Hatton provide support for the above mentioned comment.
We all extol the benefits of our favourite programming language whilst denigrating other languages less attractive to us.  In truth, published data from around the world of which Table 2 is a subset shows  that there is no clear relationship between programming language and the defect density of systems implemented in  that  language.    Ada,  for  example,  supposedly  far  more  secure  than  other  languages  produces systems of comparable defect density.  In contrast,  C is reviled by many  safety-related  developers and yet it is responsible for some of the most reliable systems ever written.   We  can  conclude  that programming language choice is at best weakly related to reliability.
However, I doubt his conclusion from
a  recent  study  comparing  two  similar  systems  of  similar  size,  (around 50,000  lines each), one  in  C  and  one  in  object-designed  C++,  the  resulting  defect  densities  were shown  to  be  around  the  same  at  2.4  and  2.9  per  1000  lines  respectively,
that
that language has little effect on reliability, object-oriented or not  and  that  the  massive  drive  to  object-orientation  is  another  giant  leap  sideways  in  which  the software industry appears to specialise.
It is unfair to conclude a programming paradigm is defective or fail to live up to its touted benefit from observation on a programming language. This is particularly true for C++ which actually is hybrid in nature - a better-C and Object-Oriented programming language.

From my personal development experience and reviewing code, a person using an object-oriented language, be it C++, C# or Java, does not necessary mean that the developer is apply sound OO principles to their creation. It is the use of these principles that give rise to the touted benefit. 

If they are not applied, C++ and other object-oriented language can result in system with far worse defects and undesirable features than say a procedural language like C. Lakos echos similar sentiment:
It is completely wrong, however, to think that just using C++ will ensure success in a large project.


C++ is not just an extension of C: it supports an entirely new paradigm. The object-oriented paradigm is notorious for demanding more design effort and savy than its procedural counterpart. C++ is more difficult to master than C, and there are innumerable ways to shoot yourself in the foot. Often you won't realize a serious error until it is too late to fix it and still meet your schedule, such as indiscriminate use of virtual functions or passing of user-defined types by value, can result in perfectly C++ programs that run ten times slower than they would have had you written them in C.
[...]
Unfortunately, the undisciplined techniques used to create small programs in C++ are totally inadequate for tackling larger projects. That's to say, a naive application of C++ technology does not scale well to larger projects. The consequences for the uninitiated are many.


"Large-Scale C++ Software Design" by John Lakos, page 2, Anddison Wesley Longman Inc. 1996

Wednesday, June 29, 2011

What a piece of gem

I am so glad that I have rediscovered this piece of gem titled "Good practice in software" by Les Hatton. It should be read by any aspiring or experienced developer. It is full of timeless advices and facts, like this:
Perhaps the biggest surprise in an industry awash with technology is that it doesn’t seem to make much difference. By far the biggest factor which emerges in most studies is the individual quality of the engineers who build a system and a few common-sense principles.  We have known this since the admirable book by Fred Brooks, [6] which every aspiring software producer should read. Rather than absorbing this powerful lesson, the computing industry became obsessed with the notion that the process or bureaucracy of building software was the most important part.  The evidence is to the contrary.  No matter how well- defined a process, the quality of the product still depends mostly on the quality of the engineers who build it. To this, a good process can bring consistency and accountability.
So true! People are forever darting from one language to another or from one technology to another in an escapist attitude to avoid the hard slog of learning the trade!

Wednesday, May 5, 2010

Joke of the century - Steve Job calling Apple iPad/iPhone open system

Steve Jobs must be using a different dictionary than mine and may be high on illicit substance when he said:
Apple has many proprietary products too. Though the operating system for the iPhone, iPod and iPad is proprietary, we strongly believe that all standards pertaining to the web should be open. Rather than use Flash, Apple has adopted HTML5, CSS and JavaScript – all open standards.

While the web part may be so only in a very limited sense. It still does not work with 80% of the web that other browsers can competently handle. It is like saying my car's ride is so good only one perfectly laid road surface but any pot-holes or expansion joints will throw the car off course.

What he did not say is that it is not open to industry adopted defacto "standards" (Steve you quoted the word open and I quoted the word standard, fair swap!), of which Adobe Flash is one, even though it API and standards belonging to Adobe.

If Apple, in particular, is so open as Steve Jobs, why is there a dictatorial control over what development languages one can use?

The whole issue is not whether Adobe Flash is proprietary or not. It is just the culture of Apple's insatiable thirst to retain control over its products - Google Voice Native removal - and it will not allow others invention to outshine his.

The so called "open" system supports Object-C, which does not have any formal written standard unlike ANSI-C or ANSI-C++. Even C# is an ISO & ECMA standard language and hence if Steve is genuine about pursuing only standard or open specification, he should endorse .Net but it is in the banned list.

I can't understand why Microsoft has been charged for anti-competitive when it only have Internet Explorer pre-installed while allowing all other browsers under the sun, including that from Apple, can installed without need for approval and yet Apple is free to impose all the kind of undocumented approval rules that in its tight-fist control of its product.

If it is good for the gander, it is good for goose! So just can't wait to see the US Department of Justice, FTC and EU coming down hard of this villain. It is long overdue.

Friday, March 12, 2010

.Net Object Construction and Serialization caveats

In the last several days, I was deeply investigating the WCF and in particular with the DataContract and the serialization issues using DataContractSerializer.

I constructed a very simple data type like this:
namespace Bookshop
{
 [ DataContract ]
 public class Book
 {
  string title;
  List<Person> authors = new List<Person>();
  public Book() {
   Debug.WriteLine( "Book Default C'tor" );
  }
  
  public Book( string title, params Person[] authors ) {
   Debug.WriteLine( "Book Other C'tor" );
   this.title = title;
   this.authors.AddRange( authors );
  }
  
  [ DataMember (Name="ti") ]
  public String Title {
   get{ return this.title; }
   set{
    Debug.WriteLine( "Title set" );
    this.title = value; 
   }
  }
  
  [ DataMember ( Name="au" )]
  public Person[] Authors {
   get{
    Debug.WriteLine( "Getting an array of Persons" );
    return this.authors; 
   }
   set {
    Debug.WriteLine( "Authors set" );
    //if ( this.authors == null )
    //    this.authors = new List();
    //else
                                // Why NullReferenceException?
    this.authors.Clear();   
    this.authors.AddRange( value );
   }
  }
 } 
 
 //=========================================================
 [ DataContract ]
 public class Person {
  string firstName;
  string lastName;
  Int32 id;
  public Person( Int32 id, string firstName, string lastName ) {
   this.id = id;
   this.firstName = firstName;
   this.lastName = lastName;
  }
  
  [ DataMember ]
  public Int32 Id {
   get{ return this.id; }
   set{ this.id = value; }
  }
  
  [ DataMember ( Name="fn" ) ]
  public String FirstName {
   get{ return this.firstName; }
   set{ this.firstName = value; }
  }
  
  [ DataMember (Name="ln") ]
  public String LastName {
   get { return this.lastName; }
   set { this.lastName = value; }
  }
 }
}

The classes look contrived but that is besides the point. The coding style and usage are inline with recommendation.

However, during a unit test like this:
[Test]
public void TestSerializeAndDeserializeBook()
{
  Book book = new Book( "Testing Serialization and Deserialization",
              new Person( 100, "Tom", "Smith" ),
              new Person( 101, "Peter", "Pan" ) );
  DataContractSerializer ser = new DataContractSerializer( typeof(Book) );
  using( Stream stm = new MemoryStream() )
  {
    ser.WriteObject( stm, book );
    stm.Seek( 0, SeekOrigin.Begin );
    Debug.WriteLine( "Begin to deserialize" );
    Book regen = ser.ReadObject( stm ) as Book; 
Assert.IsTrue( Object.ReferenceEquals( book, regen )!=true, 
              "Expecting them to be distinct objects" );
    Debug.WriteLine( "Asserting regenerated Book object" );
    AssertBook( book, regen );
  }
}
The test reveals some runtime mistake that only manifests in a deserialization situation. I will deal with that first and my solution later. I was puzzled by this.

I have obviously forgotten my reading on ECMA-335 and have only remember section  8.9.6.6 (Partition I):

New values of an object type are created via constructors. Constructors shall be instance methods, defined via a special form of method contract, which defines the method contract as a constructor for a particular object type. The constructors for an object type are part of the object type definition. While the CTS and VES ensure that only a properly defined constructor is used to make new values of an object type, the ultimate correctness of a newly constructed object is dependent on the implementation of the constructor itself.
What I have forgotten is that there is a CLS (framework) notes attached to this section that reads:
[Note:
[...]

CLS (framework): Can assume that object creation includes a call to one of the constructors, and that no object is initialized twice. System.Object.MemberwiseClone (see Partition IV) and deserialization (including object remoting) shall not run constructors. end note] 
This note gives permission to deserializer not to run the constructor. This explains precisely why in the above unit test that a NullReferenceException is encountered when deserializing the Book object from the stream. Drilling deeper reveals the exception is being thrown when I try to clear the List in the property setter of Authors.


In normal usage, the Book.authors initializer is guaranteed to look after that and is supposed to be executed before the first line of code in the body of the constructor. But because a deserializer is permitted to not to call the constructor, the initialization code for Book.authors is skipped thus become null. Interesting and more on this.

So digging further in ECMA trying to understand the mechanics behind this issue, I have found this Partition III section 4.5, there is an IL instruction called initobj, which simply
initializes an address with a default value. typeTok is a metadata token (a typedef, typeref, or typespec). dest is an unmanaged pointer (native int), or a managed pointer (&). If typeTok is a value type, the initobj instruction initializes each field of dest to null or a zero of the appropriate built-in type. If typeTok is a value type, then after this instruction is executed, the instance is ready for a constructor method to be called. If typeTok is a reference type, the initobj instruction has the same effect as ldnull followed by stind.ref.

Unlike newobj, the initobj instruction does not call any constructor method.
and the newobj (in Section 4.21)
allocates a new instance of the class associated with ctor and initializes all the fields in the new instance to 0 (of the proper type) or null as appropriate. It then calls the constructor with the given arguments along with the newly created instance. After the constructor has been called, the now initialized object reference is pushed on the stack.

From the constructor’s point of view, the uninitialized object is argument 0 and the other arguments passed to newobj follow in order.

All zero-based, one-dimensional arrays are created using newarr, not newobj. On the other hand, all other arrays (more than one dimension, or one-dimensional but not zero-based) are created using newobj.

Value types are not usually created using newobj. They are usually allocated either as arguments or local variables, using newarr (for zero-based, one-dimensional arrays), or as fields of objects. Once allocated, they are initialized using initobj. However, the newobj instruction can be used to create a new instance of a value type on the stack, that can then be passed as an argument, stored in a local, etc.
So in most situations where one creates an object using new operator, newobj instruction is used. But in a deserialization, the standard permits the writer to by-pass this object creation using newobj instructions but to use initobj to initialise the member variables without calling the constructors.

There were several solutions offered to me. One of them was to create the List<person> in the property setter of Authors and then use property instead of member field inside Book. While in this contrive class, this is a valid solution but note the property type of Authors, which is an array of Person and not List<person>. One of the attraction of introducing DataContract/DataMember attributes in WCF is to allow developers to reuse as much as possible their business classes (I doubt this really works in practice - more on this) and hence the Book class may be serving other purpose. So it is no a solution but not practical in general.

Another solution is to create the List in each constructors as well as in the property setter of Authors if it is null. Doing that in the constructors will cater for the normal usage while doing that in the property setter will work for deserialization. But the coding style is not very appealing and in fact, it is identical to what is generated by the C# compiler from the initializer. From this:
public class Book
{
  string title;
  List<Person> authors = new List<Person>();  public Book()
  {
  }
  
  public Book( string title, params Person[] author )
  {
    this.title = title;
    this.authors.AddRange( author );
  }
to this
.class public auto ansi beforefieldinit Book
    extends [mscorlib]System.Object
{
    .custom instance void [System.Runtime.Serialization]System.Runtime.Serialization.DataContractAttribute::.ctor()
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: newobj instance void [mscorlib]System.Collections.Generic.List`1::.ctor()
        L_0006: stfld class [mscorlib]System.Collections.Generic.List`1 LMar.Demo.Bookshop.Book::authors        L_000b: ldarg.0 
        L_000c: call instance void [mscorlib]System.Object::.ctor()
        L_0011: nop 
        L_0012: nop 
        L_0013: nop 
        L_0014: ret 
    }

    .method public hidebysig specialname rtspecialname instance void .ctor(string title, class LMar.Demo.Bookshop.Person[] author) cil managed
    {
        .param [2]
        .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor()
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: newobj instance void [mscorlib]System.Collections.Generic.List`1::.ctor()
        L_0006: stfld class [mscorlib]System.Collections.Generic.List`1 LMar.Demo.Bookshop.Book::authors
        L_000b: ldarg.0 
        L_000c: call instance void [mscorlib]System.Object::.ctor()
        L_0011: nop 
        L_0012: nop 
        L_0013: ldarg.0 
        L_0014: ldarg.1 
        L_0015: stfld string LMar.Demo.Bookshop.Book::title
        L_001a: ldarg.0 
        L_001b: ldfld class [mscorlib]System.Collections.Generic.List`1 LMar.Demo.Bookshop.Book::authors
        L_0020: ldarg.2 
        L_0021: callvirt instance void [mscorlib]System.Collections.Generic.List`1::AddRange(class [mscorlib]System.Collections.Generic.IEnumerable`1)
        L_0026: nop 
        L_0027: nop 
        L_0028: ret 
    }

So whether you write the creation code in the constructors or you rely the compiler to do it for you, the end effect is the same.

The biggest distraction: The code is not clear why one needs to do this because in normal usage, such construction scheme is totally unnecessary.

The solution can be found in Lowy
Using the deserializing event
Since no constructor calls are ever made during deserialization, the deserializing event-handling method is logically your deserialization constructor. It is intended for performing some custom pre-deserialization steps - typically initialization of class member not marked as data members.
So with this piece of recommendation, the Book class is modified by adding a new private member function as follows:
public class Book {
  // old code
  
  [ OnDeserializing ]  
  public void OnDeserializing(StreamingContext context)
  {
    if( this.authors == null )
      this.authors = new List();
    // any other initialization here.
  }
}

The code inside the OnDeserializing handler is unambiguous of their purpose. It does not interfere with normal usage of the Book class. This is almost the same as the special constructor when implementing ISerializable. I just wish once a class is adorned with DataContract, the compile would require a constructor like that for ISerializable, even if it is an empty one. In that way users do not forget.

Caveats on using Business class as Data Contract

While this sound attractive, but in reality, there are plenty of gotcha. For one, business class for non-trivial solution are not just a simple class or even one containing inside another. It is often a class tree or object graph. While WCF claims to be able to handle this, it can generate data from classes that contains back reference (or circular reference) or removal of duplicate records by using the preserveObjectReferences as part of the settings for DataContractSerializer. But be warn:

this approach has the following characteristics, which may be undesirable:
  • Performance. Replicating data is inefficient.
  • Circular references. If objects refer to themselves, even through other objects, serializing by replication results in an infinite loop. (The serializer throws a SerializationException if this happens.)
  • Semantics. Sometimes it is important to preserve the fact that two references are to the same object, and not to two identical objects.
[...]

It is important to understand the limitations of this mode:
  • The XML the DataContractSerializer produces with preserveObjectReferences set to true is not interoperable with any other technologies, and can be accessed only by another DataContractSerializer instance, also with preserveObjectReferences set to true.
  • There is no metadata (schema) support for this feature. The schema that is produced is valid only for the case when preserveObjectReferences is set to false.
  • This feature may cause the serialization and deserialization process to run slower. Although data does not have to be replicated, extra object comparisons must be performed in this mode.
More information on WCF Data Transfer in Service Contract is here. If you decide to ignore the above mentioned issues and pushes on to use the preserverObjectReferences, this is a discussion on how to over come this 'deficiency'.

In my opinion, it is best to use a specially crafted family of classes to support the Data Transfer Object Pattern.

Caveats using too many variable initializer

This has been briefly mentioned above that any variable initializer is basically a compiler language trick as there is no direct IL instruction. All it does is to cause the initialization and object creation code injected into each constructor as if you write them. The only difference is that the compiler always places them ahead of your code.

If you have several constructor, these variables initializers can cause some kind of mild bloating. I am not sure if the end effect is as drastic as static compiled language such as native C++. Since the JIT only compiles and loads those methods that are used, unless you use every one of the constructors in your class in a scenario, they may not all be jitted and loaded.

One recommendation is to remove all the initializers and to place the creation logic inside a function that is called by each of the constructor. In that way, it ensures the construction logic is centralised and avoids duplicated IL code being injected into the constructor body.

However, this will not work for those readonly members that can only be created and initialized in the constructor body. Doing this in a function even called by the constructor is no good.




"Programming WCF Services" by Juval Lowy, 2007. Page 93.

Thursday, November 5, 2009

Imporantce to knows what is behind the facade

A well written essay argues
there is still a need for "old-fashioned gumption" — a need to retain some mastery over tools we rely on and to explore others' potential.
[snip]
... "it can be very disempowering because people aren't really understanding what's going on in their business".
Of course, the most common tools in our business and personal lives have user-friendly interfaces, enabling the least tech-savvy to use them. An unfortunate side-effect of this, Mr Gelme says, is that "general users of technology have no idea about how an appliance really works, which means they may not know how to use it most effectively or repair it".
He adds: "Hiding the internal operation with an intuitive interface is compounded by the manufacturer's natural tendencies to protect their product from competitors and to increase sales by ensuring broken appliances have to be replaced, not repaired." This is achieved mainly through proprietary software.
Far too many developers lack the understanding of the mechanics behind the tools they use. Many relies on the tools as an escape from learning the fundamentals. As a consequence, they are at loss when problem occurs, which according to Murphy's law will inevitably occur.

Tuesday, August 4, 2009

Do software systems age analogously to humans?

Having worked in software industries for a long time, this question, posted in an introduction to a paper by the noted and respected Computer Scientist, David Parnas, in a book seems kind of obvious to me and no doubt to many practitioners. However, there are software companies that still hold this belief of "Design once last forever" philosophy and need not change at all. They are also unfortunately pursuers of this illusive Silver Bullet that another noted and respected scientist, Fredrick Brooks, has warned. They naturally do not believe software can age.

Having worked in such a nescient organisation, I am interested to read what Parnas has to say when I come across his paper "Software Aging". There are specifics that I believe worth mentioning here.

One of the good ways to slow down or even to deal with changes, is to design to cater for changes using well-known design principles. In his research and experience, sadly "I do not see much software that is well designed from this point of view" and he gave some of the reasons why:
... The principle is simple; applying it properly requires a lot of thoughts about the application and the environment. The textbooks do not make that clear.

Many programmers are impatient with such considerations; they are so eager to get the first version working or to meet some imminent deadline, that they do not take the time to design for change. Management is so concerned with the next deadline (and so eager to get to a higher position) that future maintenance costs don't have top priority.

Designs that result from a careful application of information hiding are quite different from the "natural" designs that are the result of most programmers' intuitive work.....

Programmers tend to confuse design principles with languages.... Even worse, they think that one has applied the techniques, if one has used such a language. [Sadly, in my professional experience many managers are the big champions of this (mis)belief creating massive software problems and wastes.]

Many people who are doing software development, do not have an education appropriate to the job.
Italics text are my comments.

One of the topic that he commented on that I share passionately that is often not done in Software Industry as compared with others, such as other forms of engineering and medicines is the topic of reviews despite its effectiveness supported by abundance of well publicized materials. Robert Glass even proclaims that it is "being a breakthrough as anything we have". Parnas said
it is quite astonishing to see how often commercial programs are produced without adequate reviews. There are many reasons for this:
  • Many programmers have no professional training in software at all. Some are engineers from other fields; some are "fallen scientists" who learned programming incidentally while getting education... In many of those areas, the concept of preparing and holding a design review is nonexistent.
  • Even among those that have Computer Science degrees many have had an education that neglected such professional concerns as the need for design documentation and reviews....
  • Many practitioners (and many researchers) do not know how to provide readable precise documentation of a design, as distinct from an implementation. No precise description, other than the detailed code, is available for review. Design reviews early in a project, when they would do the most good, are often reduced to chat sessions....
  • Much of software is often produced as a cottage industry, where there are no people who could serve as a qualified reviewers ....
  • Software is often produced under time pressure that misleads the designers into thinking that they have no time for proper reviews.
  • Many programmers regard programming as an "art" and resent the idea that anyone could or should review the work that they have done.
I also share Parnas' concern that "it is common to hear a programmer saying that the code is its own documentation; even highly respected language researchers take this position, arguing that if you use their language, the structure will be explicit and obvious"

My argument with proponent of this view is that code does not document a design; it merely documents an implementation of a design decision. There are plenty of materials a designer has discarded that are vitally important to the maintenance of the implementation but are not and cannot be translated to code. For example, technologies or algorithms that a designer has considered by discarded and for what reasons are not found in code and cannot be for practical reasons. Design decisions why it is done this way and not another are not found in code; in fact, lack of supplemental information that we called documentation one could be misled from reading code. They cannot be deduced from code no matter what language one uses or how clever one uses the language construct to aid documentation.

Parnas went on to say "Even if we take all reasonable preventive measures, and do so religiously, aging is inevitable." and in that paper he offers many practical advices to deal with software aging, including "start taking documentation more seriously".



Daniel M. Hoffman and David M. Weisss, "Software Fundmentals - Collected Papers by David L. Parnas" 2001. Chapter 29 "Software Aging"


Robert L. Glass, "Facts and Fallacies of Software Engineering", page 104

Tuesday, August 28, 2007

Unhealthy obsession with using executables - an example of Golden Hammer Anti-pattern

When one is obsessed with anything, it will lead to bad things - in life and in software development.

This is a real-life example of Golden Hammer Anti-Pattern [1]. The characteristic of this anti-pattern is the tell-tale signs of the blind applications of a technique without question of their validity and suitability. The story below will illustrate this concept and the harmful effect that not only has on the product but also the company culture.

This is a story of a product and suffice to say that it is a serious business application. The product has set out with a form of architecture and has for a while religious following it. However, this reliance on executable, most like came from Unix background, soon become an obsession developed into a Golden Hammer Anit-Pattern. Everything has to be an executable. COM is then used to support automation allowing one executable to incorporate functionality that is packaged in another executable.

To be fair, the product does have DLL's but they are not inproc server. Normally using COM local server is not a bad thing but when the organization is trying to put dialog boxes in a COM local server and trying to maintain the modality across the process boundary, the fool-hardiness of such obsession becomes obvious.

This obsession breeds bad programming practice. Since these local server are registered to be single-use, the developers blatantly abuse the use of global variables. Since there is no code review or mentorship, this abuse becomes cancerous making correction relatively expensive and limiting their options.

The obsession is repeated over a number of years and successfully infecting several generations of management and technical leads. No one has raised a question.

The authors [1] are spot on in explaining why this lemming-like behavior is developed:
In many cases, the Golden Hammer is a mismatch for the problem, but minimal effort is devoted to exploring alternative solutions.

This AntiPattern results in the misapplication of a favored tool or concept. Developers and managers are comfortable with an existing approach unwilling to learn and apply one that is better suited.
Further more, the authors suggest the causes of this are:
  • Ignorance, Pride, Narrow-mindedness
  • Reliance on proprietary product features that aren't readily available in other industry products.
Couldn't agree more.

Here are some of the harms in this obsession representing in real term missed opportunities to provide innovative product and to exploit new products/platform:
1) Because everything is packages as COM local server, the product is unable to provide correct user-experience reliably. Often forms packaged in another COM local server fails to sit on top of the 'owner' form (the launcher). Extraordinary amount of effects over the years are expanded on trying to fix this problem ignoring that a simpler solution using in-proc server would immediately fix this courtesy of Microsoft. Pride and Ignorance have a lot to do with the blindness in recognizing this simple solution.

2) Because the process isolation shields the developers of the harmful effect of blatant reliance on global variables, they even use global variable to do the job of the this pointer, an obvious sign of lack of training in OOP.

3) The obsession has produced a culture so blind that when they considered moving to .Net technology, as everyone did, they refused to concede the inappropriateness of the executable model in the .Net architecture. As most .Net developer would tell you that you cannot develop COM local server using .Net languages but you can for in-proc server. "Igorance" as the authors suggest the cause of this disease, blinding them so badly they ignorantly believing .Net Remoting is a replacement of COM local server that needs no registration.

Instead of taking time out "to exploring alternative solutions", they develop a technique to bend the .Net framework to maintain their obsessive behavior using .Net Remoting. This is chalk-and-cheese difference but to them this is brilliant.

The end results are excessive consumption of memory, slow start up etc. producing a laughable implementation that is neither .Net architecture nor Unmanaged COM local server one. Management did not even thought of the inappropriateness of their flawed architecture. Poor customers.

Had they been less blatant in using global variables, they could have easily transformed their code from an executable model to one using assemblies thus giving them registration-free deployment without being obese.

The authors [1] are perfectly in their observation and suggested refactor technique:
Philosophically, an organization needs to develop a commitment to an exploration of new technologies. Without such commitment, the lurking danger of over reliance on a specific technology or vendor tool set exists. This solution requires a two-pronged approach: A greater commitment by management in the professional development of their developers, along with a development strategy that requires explicit software boundaries to enable technology migration.

[snip]

In addition, software developers need to be up to date on technology trends, both within the organization's domain and in the software industry at large.... They can also form book study clubs to track and discuss new publications that describe innovative approaches to software development. In practice, we have found the book club paradigm to be a very effective way to exchange ideas and new approaches....

[snip]

... is to encourage the hiring of people from different areas and from different backgrounds...

Finally, management must actively invest in the professional development of the software developers, as well as reward developers who take initiative in improving their own work.
So true.



[1] "Anti-Patterns - Refactoring software, Architectures, and Projects in Crisis" by William J. Brown, Raphael C. Malveau, Hays W McCormick III, Thomas J Mowbray

Sunday, August 19, 2007

CBA Netbank UI gone from bad to worse

Further to my previous blog on the need to test UI on a number of Desktop settings, Commonwealth Bank of Australia's Internet Bank has just rolled out a new UI.

Sad to say that it has gone from bad to worse. See this layout distortion on 120DPI in IE6:
This is bad. The placements of all the controls are all over the places. When the same page is rendered in Firefox 2, the page layout is good compared to this.

Wooden spoon prize for CBA's Web developer.

Thursday, August 16, 2007

Test your UI with a range of desktop settings

It is getting more and more common to see badly written UI that cannot handle different desktop settings. One reason is that most so called UI text book does not talk about DPI (Dots Per Inch) display settings.

Everyone assumes that it is always the default - 96 DPI. Sorry I have news for you. When you write a Windows program, there are certain things that belong to the users and there are things within your control. One of the things that is beyond your control is Desktop display settings but the operating system has functions to allow you to discover them and to react accordingly. The last bit is often left out by the programmer who then assumes the defaults or the same settings as their desktop.

To change this setting in XP, just bring up the Display applet in the Control panel, go to the Settings tab, then press Advanced button. In the general tab you can change the DPI settings. Many do not even know about this.

My development machine is always set to be different from the standard to catch violators - myself included. It can also work the other way - a program developed with 120DPI will not display properly in 96DPI environment.

So you need to test both and the best way is to use a Virtual Machine. Fortunately WinForm in .Net 2 has a built in facility to adjust for these.

Below are some bad examples.

From the internet banking department of one of the largest banks in Australia - Commonwealth Bank of Australia:When the 'menu' is dropped down, the distortion is more pronounced:

The bank's did not actually leave their customers in the dark. Here is a cop out from the bank:

Why do the navigation tabs within NetBank (i.e. View Accounts, Transfer Money, Bills, Admin & Services) appear to be so large or small?

This could relate to the Dots Per Inch (DPI) setting on your computer.

The normal DPI setting is 96 DPI. If you are using Windows XP the best way to check your DPI setting is as follows:

  • Open Display icon in your control panel;
  • On the Settings tab, click Advanced
  • On the General tab, in the DPI setting list, click the DPI setting you want to use.
This is a real cop out because such demand is not necessary as million of other web pages can handle this issue without any problem. I suggest that it is their programmers' lacking the skill to deal with this. One of their subsidiaries' web page handles this perfectly.

On a smaller scale, the popular NantAddin for Visual Studio demonstrates a very commonly made mistake:

The almost disappeared OK and Cancel buttons are marked in red rectangle.

Wednesday, June 27, 2007

Two very poorly understood and appropriately staffed roles in software house

Many years ago, I met a young software engineer who was considering whether or not to take up a role as a software installation writer in a software company, which was classified in the top largest private software company of a country.

Since he was worried that it would be a mundane job with probably no future into development and to improve his knowledge in Windows, I had a long conversation with him pointing out the following key aspects:
  1. It is a role poorly understood and poorly rewarded by management
  2. It is a role that holds the make or break in the success of delivering a piece of software into customer's machine.
  3. Its creation is the first point of contact with the customer and the customer's positive or negative impression of the software largely influenced by this piece of software.
  4. The person needs more skill, thus my early comment on reward, than developers of the software, as he has to ensure he knows all the quarks and weird configurations out there. Often he has no way of knowing with precision. More importantly he needs skill to detect them to plan evasive actions. On top of that of course he also needs to be aware of the make up of the software he is installing, its requirement of OS support, its hardware/software dependency, if any.
  5. He also needs to know the right way to install the software and uninstall it cleanly and in such a way not violating the Windows security.
  6. He also needs to be a competent developer so that he can supplement the installer script. Often he needs to know C/C++ as often times, that is all he can rely upon in that very instance.
He was initially skeptical of my assertion because that was the general, and still is, trend but he did take the job. After a few years on this role, he agreed with me wholeheartedly. Over the years, I have observed the same misunderstanding being repeated time and time. The manager always thinks that it is a matter of pressing a few buttons in say InstallShield to crank out the installation package so simple that it can be given to the most junior staff. Sure, some simple application would only require simple installation package. But as the sophistication grows, such naive observation at time can prove fatal.

This is the first role that I have always maintained, a view formed from the trenches, that is extremely poorly understood and appreciated by management. I tip my hat to those installer script writers whose products flawlessly guided me through, particularly OS installer.

The second role is the Build Master. I have always thought of this but do not have the same strong convection as the Installation Writer. But the book "The Build Master - Microsoft's Software Configuration Management Best Practices" by Vincent Maraia, finally tips me over.

As Vincent says:
Many project and program managers think that the actual building of a project is a pretty trivial. Their attitude is that they can simply have the developer throw his code over the wall and hire someone to press a Build button, and everything will be fine.
[...]
I recommend that you consider the build process a piece of software that you regularly revise and deploy throughout your product team.
Many projects that I have worked on or reviewed do not even have an automated project build process. Different parts of the project are built in various machines in ways no one knows what settings are used. How can such ad hoc and haphazard arrangement manages to produce consistent and reliable product? It is just sheer luck.

Once again, management, as Vincent said in his book, does not understand the skill and reason for the Build Master.

Saturday, June 23, 2007

Bug reporting - a lesson CodeGear can learn from Open Source

My recent usage of the GNU Win32 port of Grep resulted in my discovery of a bug and in custom with my practice, I filed a report. What happened next is a lesson that Borland/CodeGear should learn from the Open Source community.

Not only did they not whinged, throwing up excuses, calling their user and bug reporter not understanding their 'feature', they digested my bug report carefully and promptly acknowledged that was a genuine bug. Even when Borland's bug has been proven beyond doubt, yet they still refused to fix it.

Within a short time, they posted me a message advising me a bug fixed version is available. Full mark for that.

Contrasting that with CodeGear's Delphi bug reports I have filed over the years, I have never received this kind of acknowledgment and quick response. More disturbingly CodeGear's Delphi product is NOT FREE and yet providing far worse support than free stuff. Hence, price does not equate to provision of support, not even meager support.

People considering CodeGear software needs to remember this before spending your money.

Saturday, June 9, 2007

Different approaches in handling users' bug report

I have used many software libraries and software packages over the years and whenever I discover something that does not agree with the intended usage, I always take the time and effort to develop the simplest scenario to demonstrate the anomaly. Then I will submit this to the developer for comments. Since I am a developer, I know one cannot always be right and if someone can show you a scenario that can duplicate the anomaly, it is a great help as half the work is done to improve the product.

Below are a number of cases of my fault reporting experiences and the vastly different experiences I have encountered. You be the judge who should deserve the wooden spoon.

Possible Microsoft Enterprise Library bug - Range Validation configuration.

Recently, I have decided to use the Microsoft Enterprise Library 3.0 and in particular the Validation Application Block. During my experimentation with using the Configuration Console, I have discovered the console is not behaving logically. After extensive experimentation, I have formed the opinion that the validation process used in the console is faulty preventing me to save the configuration file and that a work around has been found.

So I fired a comment to the forum responsible for the Ent Lib to seek the expert opinion. With speed commensurates with Internet Time, the moderator of the forum recognized a bug and raise a work item. Full mark for their effort.

Something amiss - two minor releases of Gnu Win32 port of grep behaving differently

I am a frequent user of this great tool called grep that is rooted in Unix. Recently, I had to perform some recursive search using regular expression in some C# files. I found a version of grep in my machine that allowed me to successfully locate the lines with this command line:
 grep -R --include="*.cs" -P "^[ \t]+class" *
I looked at my grep and realized it was slightly dated and wondering if there was more recent one. So I searched Google and found the two sites on SourceForge. The GNU Utilities port to Windows (UnxUtils) and the Win32-versions of GNU tools (GnuWin32); not sure why two. To cut the story short, the UnxUtils contains a old version of grep, 2.4.1, which does not have the --include and -P (the Perl Regular Expression) switches.

In the latest version of GnuWin32 version 2.5.1a-1, it has the grep with the required switches. However, it does not function according to the man page. On that site it also has an earlier release, 2.5.1a, and surprisingly, this version not only has the required switches, they function according to the man page.

Seeing these distinct differences in behavior, I duly submitted a bug report. The information provided must be clear enough to indicate something was wrong and the status had been changed and assigned to someone for further investigation. It could mean my usage of the switches combination is wrong too. In that case, 2.5.1a-1 needs to be correct. If my usage is right, and I am pretty sure I am right, the 2.5.1a-1 needs to be compared to 2.5.1a and rectified accordingly.

Problem in Borland's Delphi library.

I must admit that I am not a long time user of Borland's Delphi programming language but in the last 2 years, I have begun reading code and writing code in Delphi - both the Win32 and Delphi.Net, of course including the VCL.Net.

I am also fortunate that I am surrounded by Delphi experts who can either correct my usage or advises me of this 'Delphi specialties'. They have also fed me many interesting stuff and many I have taken on as a challenge to get them fixed as they are clearly illogical.

Many are definitely bugs while others are of their own creation. A samples can be found in this blog for example, Delphi handles COM Server, or trying to change ECMA CLI standard. There are others that are not reported in my blog.

It is particularly interesting to note that the COM problem was first discovered in Delphi 3 and numerous users tried in vain to have this rectified. The support would preferred to argue at length of the classification of this problem than to discuss the technical issues. Perhaps they were not skillful enough to understand.

My discovery actually unearths a possibility that someone in Borland has accidentally deleted the line testing the start up mode and the code still compiled correctly giving Borland an impression of correctness.

They do not see anything wrong when they are not developing in LUA. Thanks Borland for giving me a real life illustration of the danger for not developing in LUA. This may be the same reason why their TRegistry fails too.

Even putting this aside, my code analysis of their code clearly indicates that Borland's developers do not know what is the exception handler and thus have thrown the wrong exception or vice versa. This allows the application to crash catastrophically during start up.

With only 9 lines in dispute and a well described test scenario, they steadfastly maintained that there was no bug. If that is the case, why would an automation server, that is running as a stand alone, thus not requiring to be registered, fail to run in LUA? When cornered, Borland offered all sorts of stupid 'fixes', like using special registration to HKCU hive.

Stubbornness does not fix code. It only gives developers more reason to look down on this product. It gives me indisputable examples showing the poor quality of the product and more convincing argument in product evaluation or elimination. Developers that following my suggestion to address this issue came out smiling without the need to use unorthodox hacks and even considering the laughable work around from Borland.

My blog has documented many other reports of these kind of encounters. Some of the 'incorrect behaviour' are trying to be justified as features. While others the company could not bother to comment.

To be fair, their developers had acknowledged some of my finding, not documented here, to be more than spot on, exploring areas that they had not considered. But that was as far as it went. Hardly called satisfactorily resolved.

A far cry from other more mature and definitely users friendly companies or communities.

I will definitely be monitoring the Delphi 2007 to see if these issues are addressed. If they cannot even admit fault, the first step in fixing any bug, my bet is that the fault will still be there. So if you were considering upgrade, check these issues out first or else you may be getting the same old thing with a new wrapper!

Tuesday, May 29, 2007

The world without Visual SourceSafe

I am not here to bash Visual SourceSafe as I still believe that it is a great tool for simple development shop but to explore the world after leaving VSS. What are the possibilities on offer?

The primary aims are to keep as much cash in my pocket rather than putting them in some vendor's pocket and that it has to scale up.

What can scale up better than source control system that are routinely used by Internet Open-Source communities? Hence there are CVS and Subversion. I have used CVS and not at all impressed with it and since Subversion (SVN) is a replacement of CVS, I will concentrate on it instead.

The other on offer is VSTS with TFS from Microsoft. Since my MSDN subscription can let me use this and that it is a fairly common toolset, I will also explore this one too. The fact that it is becoming like a giant octopus reaching out and trying to be a tool for everything worries me. Others such as ClearCase, I can't afford and my dislike of it has subsided considerably after my discovery of TFS as revealed below.

There are enough centralised materials on TFS that need not be repeated but Subversion route is more interesting and is free!

One of the things that stunned me when looking at VSTS/TFS as a VCS is that it has taken away the facility of keyword substitution of things like $Revision:$, $Date:$ or $Log:$ (keywords available in VSS) in the source file to brand it. They are god-send when you have a few copies of them lying around.

In these days of ubiquitous USB memory drives, the chance of having a few copies of the same file is extremely high. Without any form of identification, you will be spending hours resolving the differences.

To me, this is a philosophy that someone is trying to ram that into the customer's throat and is a classic example of "Why Software Sucks...". The fact is that the repository has all these pieces of information and the software refuses to allow the users to use them as they see fit. Their developers should be reminded that "You are not the user" principle.

This is not just VSTS/TFS dogmatic approach in pursue of their philosophy but out of the box, ClearCase does not support this too. But at least in ClearCase, one can add a script that is called when one checks in a file to extract those information from the repository and injecting them into the source file. Microsoft, I hope you are listening.

It is also interesting to compare the philosophy used in Subversion in managing the versions.
  • It is very similar to that used in TFS.
  • It treats a set of files/folders as a tree rather than file by file as in CVS.
  • It is also atomic - meaning that if one file in a set fails to check in, the whole set will not get in.
  • The revision number applies to the entire tree not really to a file.
OK. I have left the best part last. Even though their versioning models are almost identical, SVN allows users to perform keyword substitution to inject revision number using $Revision: $, check in date using $Data: $, and the customary $Id: $ is also there too. For more information please see "Keyword Substitution" in Chapter 3 of the book, which is free. The only thing missing is to inject the change history into the file. For that I can live with it.

Good to see SVN developers that are considerate and not pushing one's philosophy down one's throat.

This alone wins me over immediately.

For Windows users, one of the disadvantage with early CVS was that there was no GUI client. SVN has fixed all that. The best is the Windows Explorer plug-in called TortoiseSVN.

For those that live day in day out inside Visual Studio, help is also available in the form of an add-in.

Finally, the Windows version of SVN with an installer can be downloaded from here free.

Armed with all the materials, I am off to explore the world without VSS. Stay tune.

Sunday, May 20, 2007

Agile Software Development

Many people thought agile software development is all about doing things fast and no need to do planning and design but let's not be too fast.

A recent report on Agile movement emphases that many have
mistaken belief by some adherents that no requirements planning or architecture should be devised before embarking on a project.
In Jim Highsmith's book "Agile Software Development Ecosystems", he said:
Agility means quickness, lightness, and nimbleness - the ability to act rapidly, the ability to do the minimum necessary to get a job done, and the ability to adapt to changing conditions.
[...]
They become skilled, and Agile, from long hours of training and effective mentoring. Sometimes their drills are repetitive and prescriptive, but only as part of learning.

Agility also requires discipline and skill. A skilled software designer can be more agile than a beginner because he or she has a better sense of quality.
[...]
"You need to have a very good discipline in place to be able to respond in turbulent times, yet simultaneously know when to be 'undisciplined.' I view anticipation to be actively seeking situations where the generally accepted guiding rules or principles no longer apply, or where shortcuts are the least risky approach to take to gaining some objective. To be able to understand when the rules don't apply, you need to completely understand when they do"..... He has to be skilled before he could be agile.

Agile individuals can improvise, they know the rules and boundaries, but they also know when the problem at hand has moved into uncharted areas. They know how to extend their knowledge into unforeseen realms, to experiment, and to learn.
These paragraphs in his book are so accurate in describing the agile software development that everyone considering adopting any agile approach should recite. I recommend this book to anyone serious about adopting Agile Software Development. This book lacks a lot of hypes that are frequently found in books trying to sell this movement.

However, far too many managers and developers only thought agile software development as a free ticket to experiment, and forgetting the to learn bit. Manager has forgotten about using skilled person who are more agile than a beginner and discipline to carry out the project. In turbulent times, they opt for 'undiscipline' approach rather than disciplined. No wonder so many managers have a bad run with Agile movement.

The conference pulled no punches and declared that "Transitioning to agile can be difficult". Don't try to introduce this if you have an important product to deliver on time when you have no experience in Agile Development.

How do you get skilled people? These paragraphs provide the answer. Sadly, managers have conveniently overlooked this.

These paragraphs also answer how 'pair-programming' works in agile movement. Often people would argue that you do not need to start the project with skilled people because pair-programming would lift the game. According to Jim, Agile developers are skilled "from long hours of training and effective mentoring". Otherwise, pair-programming would exploit human frailty by gyrating to a comfort zone, which may not produce the desirable result. Most likely, like many things in life, it is harder to develop virtuous habit than bad ones.

Saturday, December 9, 2006

More Trouble with Programming

The the second part of the interview with Bjarne Stroustrup can be found here. Several of his observations reported in this interview are worth noting.

When he was asked to comment on the "coolest" program, this is what he had to say:
"What is common to these examples of code is that they cleanly separate concerns in a program, allowing separate developments of parts. That simplifies understanding and eases maintenance. These basic language techniques allow separate "things" to be separately represented in code and combined only when needed."

When he was asked to comment about the desire to "dumb down" programming languages so that more people can develop program, his observation is spot on:
"I think that would be misguided. The idea of programming as a semiskilled task, practiced by people with a few months' training, is dangerous. We wouldn't tolerate plumbers or accountants that poorly educated. We don't have as an aim that architecture (of buildings) and engineering (of bridges and trains) should become more accessible to people with progressively less training. Indeed, one serious problem is that currently, too many software developers are undereducated and undertrained.

Obviously, we don't want our tools--including our programming languages--to be more complex than necessary. But one aim should be to make tools that will serve skilled professionals--not to lower the level of expressiveness to serve people who can hardly understand the problems, let alone express solutions. We can and do build tools that make simple tasks simple for more people, but let's not let most people loose on the infrastructure of our technical civilization or force the professionals to use only tools designed for amateurs."

I know of some manager's view of being a competent programmer is to know the tool's IDE. In the manager's view that's the amount of training they need.

He further remarked that,
"Most applications involve standards, operating systems, libraries, and tools that far exceed modern programming languages in complexity. What is difficult is the appreciation of the underlying techniques and their application to real-world problems.

... We need relatively complex language to deal with absolutely complex problems
."

Not only many developers lacks proper training, many lack sound understanding of the underlying techniques or mechanism. This often produces very fragile solution and they lack the skill and knowledge to explain things when they do not work.

The rest of the interview is on his view about .Net and C#.

It's worth a read.

Thursday, November 30, 2006

The Problem with Programming

This is the title of the latest interview with the father of C++, the legendary Bjarne Stroustrup. Below are snippets from this article.

When he was asked why most software is so bad. Here is his responses,
The structure is appalling, and the programmers clearly didn't think deeply about correctness, algorithms, data structures, or maintainability. Most people don't actually read code....

that "we" (that is, we software developers) are in a permanent state of emergency, grasping at straws to get our work done. We perform many minor miracles through trial and error, excessive use of brute force, and lots and lots of testing, but--so often--it's not enough.

So very true observation. So how can we fix this, when asked, and here are his comments:
In theory, the answer is simple: educate our software developers better, use more-appropriate design methods, and design for flexibility and for the long haul.

Reward correct, solid, and safe systems. Punish sloppiness. In reality, that's impossible. People reward developers who deliver software that is cheap, buggy, and first. ....

On the other hand, just muddling along is expensive, dangerous, and depressing. Significant improvements are needed, and they can only come gradually. They must come on a broad front; no single change is sufficient.


Yes perfect observation and comments. I am seeing this kind of practice on daily basis.

Blog Archive