Oct 30, 2010

Semantics only works in a context

I am a believer of semantics. What is why name the domain as semanticsworks.com. But let me take a step back to explain what I mean semantics here. You may find the definition in Wikipedia, but what I mean semantics here is the true intention or need to do something. For example, when I say " I need a car to go to work", the true intention is "I need get to work", "a car" is just a means, or an implementation. If I work at home, I wouldn't need a car at all. As a software developer, I can easily apply semantics into programming. For example, I would prefer writing semantic html rather mix presentation html, I would focus on abstraction(interface) rather on implementation(class) and so on. When I study a a new technology, a new programming language, I will first think what problem it is trying to solve, then I focus how it solves the problem more efficiently and elegantly. When I want to propose my solution or design to my client, I would raise the what the existing problem is, and how my solution solve the problem in a better way. Semantics seems to work. But one important thing shouldn't be forgotten, that is a context. Here is what javascript guru Douglas Crockford said in his Loopage presentation


A little while ago I was talking to a friend of mine — a really bright guy, one of the smartest programmers I know – about what we should do next with JavaScript. I suggested to him that we should get the tail recursion thing going, we should get that fixed. Why do we want to do that? Well, I said, among a lot of other things it would allow us to do continuation style passing. I think that would be a useful option for us to be able to provide within the language, and if we don't optimize the tail calls then we don't get that. His answer was: I've never used continuation passing, so I really don't see the value of it, which I immediately recognized as a really stupid answer.

The way I was able to recognize it so fast is that I have used that same argument myself, and I've been hearing that same argument throughout my entire career. Basically, the core of that argument is: "I'm not qualified to make a decision about that. The onus is on you to educate me deeply about this thing that I'm not even interested in." There's no way to overcome that kind of requirement, nobody can win that argument. But it turns out that usually that reasoning is wrong. I've heard that argument about why we shouldn't have to worry about closure. I've heard it about why we shouldn't use recursion. I've heard it about why punch cards are better than timesharing. You can go all the way back to 'it's better for us to be programming with digits, I don't understand why we need compilers'. It's been going on from the beginning. That's why software development is so slow, because basically we have to wait for a generation to die off before we can get critical mass on the next good idea.

Semantics does not always works as we expect. Seemingly, Crockford forgot his friend's context. He should have let his friend buy in his context in the first place. When you try to propose a solution to solve a problem, which your client does not think as a problem, or does not see a need to solve it immediately, then your semantics will not work in your client's context. So here is what you can do.


  1. Think in the context of your client, don't propose a solution to solve a problem that your client has not interest in solving, only propose the solution in your client's context
  2. Think in the context of your client, guide your client to think in your context and make him believe that it is a problem, then propose your solution. Sometimes, this can be very hard, if the contexts collide heavily.
  3. Ignore your client and move on

There are lots new technologies coming, like Domain Specific Language, Cloud computing, Service Oriented Architecture etc. How soon they will be adopted will depends on how people can accept the contexts in which their designer think, and how soon people can accept these context will somewhat depend on the result the early adopters achieve.


A friend of mine asked me recently, what versioning control system should be used. I said "Git". He asked why? I said it is distributed versioning control system and it is scalable. Then He said, "We don't need it to be distributed.". You know, I made the same mistake, I lost the context of friend.

Oct 14, 2010

Stop fighting

JavaScript is a amazing language, and it continues to amaze me. But I learned it in the hard way because I was trying to translate it into classic OO concept, and I failed. Douglas Crockford is my JavaScript idol, here is what he says how he finally understands JavaScript.

Eventually I figured out what was going on. After a lot of struggle, I eventually figured out that it was a functional language, and at that moment I stopped fighting it. I remember when that moment occurred, I was bicycling. I had just read the ECMAScript standard, which is a really difficult thing to understand. But I read through it, and then I had this epiphany when I was miles away from a computer. Oh, it's got functions in it, there are lambdas — I can do this now. It completely changed the way I thought about the language. In the end, the story ended successfully. We finished on time and on budget, Turner shipped it, and everything went great.

The lessen that I learned is to stop fighting against new idea with my old knowledge. New idea may be odd, but it will be appreciated if you follow along, and it expresses similar semantics in the way you never thought of. I love the philosophy of Chinese philosopher Zhangzi, here are two pieces of excerpt that I feel helpful to understand new idea.


The Ruler of the Southern Ocean was Shu, the Ruler of the Northern Ocean was Hu, and the Ruler of the Centre was Chaos. Shu and Hu were continually meeting in the land of Chaos, who treated them very well. They consulted together how they might repay his kindness, and said, 'Men all have seven orifices for the purpose of seeing, hearing, eating, and breathing, while this (poor) Ruler alone has not one. Let us try and make them for him.' Accordingly they dug one orifice in him every day; and at the end of seven days Chaos died.

Paoding was cutting up an ox for the ruler Wen Hui. Whenever he applied his hand, leaned forward with his shoulder, planted his foot, and employed the pressure of his knee, in the audible ripping off of the skin, and slicing operation of the knife, the sounds were all in regular cadence. Movements and sounds proceeded as in the dance of 'the Mulberry Forest' and the blended notes of the King Shou.' The ruler said, 'Ah! Admirable! That your art should have become so perfect!' (Having finished his operation), the cook laid down his knife, and replied to the remark, 'What your servant loves is the method of the Dao, something in advance of any art. When I first began to cut up an ox, I saw nothing but the (entire) carcase. After three years I ceased to see it as a whole. Now I deal with it in a spirit-like manner, and do not look at it with my eyes. The use of my senses is discarded, and my spirit acts as it wills. Observing the natural lines, (my knife) slips through the great crevices and slides through the great cavities, taking advantage of the facilities thus presented. My art avoids the membranous ligatures, and much more the great bones. A good cook changes his knife every year; (it may have been injured) in cutting - an ordinary cook changes his every month - (it may have been) broken. Now my knife has been in use for nineteen years; it has cut up several thousand oxen, and yet its edge is as sharp as if it had newly come from the whetstone. There are the interstices of the joints, and the edge of the knife has no (appreciable) thickness; when that which is so thin enters where the interstice is, how easily it moves along! The blade has more than room enough. Nevertheless, whenever I come to a complicated joint, and see that there will be some difficulty, I proceed anxiously and with caution, not allowing my eyes to wander from the place, and moving my hand slowly. Then by a very slight movement of the knife, the part is quickly separated, and drops like (a clod of) earth to the ground. Then standing up with the knife in my hand, I look all round, and in a leisurely manner, with an air of satisfaction, wipe it clean, and put it in its sheath.' The ruler Wen Hui said, 'Excellent! I have heard the words of my cook, and learned from them the nourishment of (our) life.'

Oct 4, 2010

Static class vs Singleton

Design pattern question is often asked in interview for developer. In an interview, I was asked to describe one design pattern that I am familiar, except singleton. Maybe the interviewer think that Singleton is too easy to answer. Yes singleton is a very simple, a sample is as follow.


class Program
{
 static void Main(string[] args)
 {
  Printer.Instance().Print();
 }
}

class Printer
{
 static Printer _printer;

 public static Printer Instance()
 {
  if (_printer == null)
  {
   _printer = new Printer();
  }
  return _printer;
 }

 protected Printer()
 { }

 public void Print()
 {
  Console.WriteLine("printing...");
 }
}

Although Singleton pattern is simple, it can be also used to test applicant's understanding of object. Let's say, if someone writes the following code some code argues that design pattern is useless, structured procedure is better. In some case, structured procedure is just as good. Can you write some code demonstrate in what scenario Singleton solve problem that static method cannot solve? (Don't think of mullti-threading, it is not an issue here.)


class Program
{
 static void Main(string[] args)
 {
  Printer.Print();
 }
}

static class Printer
{
 public static void Print()
 {
  Console.WriteLine("printing...");
 }
}


My answer

Although two solutions look similar, but it reflects different thinking. One of book affect me most in my programming career is Object Thinking. In this book, it says


The essential thinking difference is easily stated: “Think like an object.” Of course, this statement gets its real meaning by contrast with the typical approach to software development: “Think like a computer.” Thinking like a computer is the prevailing mental habit of traditional developers.

The singleton solution is reflection of "think like an object". When you think like an object, you are also an object, the other objects will be your buddies. You will interact with printer buddy by his interface. As long as your buddy expose the your printer interface, you know how to communicate with him. It doesn't matter who your buddy is, what matters is you know what kind of service your buddy provide you. You scenario will be, I see a Printer guy, he is the only printer guy, I don't care who he is, but he says he can print, so I ask him, "Print, please". If you think this way, you can write the following code. This is fundamental feature of object-oriented technique, polymorphism.


class Program
{
 static void Main(string[] args)
 {
  Printer.Instance().Print();
 }
}

abstract class Printer
{
 static Printer _printer;

 public static Printer Instance()
 {
  if (_printer == null)
  {
    Type pritnerType = GetPrinterTypeFromConfiguration();
    _printer = Activator.CreateInstance(printerType) as Printer;
  }
  return _printer;
 }
  public abstract void Print();
}

class LaserJetPrinter : Printer
{
   public virtual void Print()
   {
      Console.WriteLine("hhhhhhhhhhhh");
    }
}

class InkJetPrinter : Printer
{
   public virtual void Print()
   {
     Console.WriteLine("kakaka");
    }

}

If you think like a machine, your mindset will be like, I am the master of the printer, I want feed it with some instructions. Ok, I have menu of the machine, one of instruction is "print", let me feed it, and it prints. If you think like this, you will write the static method like above. This is not necessary bad practice, in fact it is even the best practice(please check CA1822: Mark members as static, if you never want to have differently print behavior. Until then You have much less flexibility, and OO is your friend.