Archive for April, 2010

Uncategorized

A Good Architect / Team Lead

Here's my top 10 for a good architect / team leader (in no particular order):

  1. Has superb technical and communication skills that make him/her equally adept at communicating to business stakeholders and technical personnel.
  2. Owns the day-to-day execution of a team by comitting to objectives, driving decision-making, and removing obstacles.
  3. Understands the current and likely future requirements of the business and designs a solution that will allow low-cost changes along anticipated change vectors.
  4. Finds simple solutions to complex problems but, if need be, employs complex solutions such that the complexity is abstracted away from developers.
  5. Ensures key infrastructure pieces have strategic closure so that team members don't need to ingest large doses of non-business-related code.
  6. Cares about not only the technical and algorithmic aspects of technical solutions, but how these impact other team members in terms of productivity and frustration (aka inertia reduction).
  7. Listens to feedback from others and cultivates a collaborative, innovative culture because he/she understands that good ideas can come from anywhere.
  8. Holds the vision that the team is following, and can espouse that vision to others.
  9. Insulates the team from external influences when necessary.
  10. Is capable of attracting and retaining phenomenal developers because of the value they see in working with said architect/team lead.

Uncategorized

Lifted Conversions and Operators in C#

Lifted Conversions
These apply to nullable value types that were introduced in .NET 2. Prior to this reference types were obviously nullable but value types, like int, long, double, decimal, etc, were NOT nullable making it hard to figure out if a value had been set or not without resorting to initializing the value types with some "magic value" like -1. The language designers for .NET implemented the Nullable construct as a struct that wrapped a base value type, T, and conveniently there is a generic constraint to restrict T to be a value type [ where T: struct]. Now, rather than re-implement all the implicit conversions between value types for nullable value types they adopted a policy of lifted conversions from the underlying base value types. This is best illustrated with some some code doing implicit conversions:

    1 int i = 1;

    2 long j = 1;

    3 

    4 int? ni = 1;

    5 long? nl = 1;

    6 

    7 j = i;      // fine

    8 nl = ni;    // fine

    9 

   10 i = j;      // Compile error - downcasts need to be explicit

   11 ni = nl;    // Compile error - downcasts need to be explicit

   12 

   13 ni = i;     // fine

   14 ni = j;     // Compile error - no implicit cast from long to int?

Line 10 indicates the expected case where a downcast from a long to an int must be explicit thus this line causes a compilation error. Line 11 is attempting to do an implicit cast from a long? to an int? and because of the lack of an implicit cast from a long to an int, it too causes a compilation error. This is in stark contrast to Lines 7 and 8 where the opposite cast is being attempted, int to long and int? to long?. Line 7 works as expected because it is a widening conversion, and Line 8 works because a lifted conversion (from int to long) is being used.

Line 13 works fine too because a non-nullable value type has a narrower range of values than it's corresponding nullable value type, so a cast from T? to T is considered safe and can be done implicitly.

Note that lifted conversions are applicable not just to the predefined value types but also to any implicit conversions defined on user-defined value-types (structs). These can be defined using code such as this...

public struct Rotation

{

    public int Degrees { get; set; }

 

    // to implicitly cast an int to a Rotation

    public static implicit operator Rotation(int value)

    {

        return new Rotation { Degrees = value % 360 };

    }

}

Lifted Operators
Along similar lines as the lifted conversions on nullable value types, lifted operators allow predefined and user-defined operators that work for non-nullable value types also to work for nullable forms of those types. In other words, operators defined on T are available to T? where T is a value type (struct).

I've often heard programmers allude to this as a form of inheritance but that isn't correct. Both user-defined and predefined operators and conversions are defined as static methods (see below) and as such are not inherited. It's because of this that the concept of lifted operators is employed. Consider this simple value type with the addition operator overloaded:

public struct Rotation

{

    public int Degrees { get; set; }

 

    public static Rotation operator +(Rotation a, Rotation b)

    {

        return new Rotation {Degrees = (a.Degrees + b.Degrees)%360};

    }

}

When someone comes along after you and creates a Rotation? your overload of the + operator effectively becomes this:

    // lifted operator for Rotation? is equivalent to...

    public static Rotation? operator +(Rotation? a, Rotation? b)

    {

        if (a == null || b == null )

            return null;

 

        return new Rotation?

                    {

                        Degrees = (a.Value.Degrees + b.Value.Degrees) % 360

                    };

    }

Effectively it does what you'd expect with the bonus null propagation logic added.

There are more subtleties involved in this (like the qualifying criteria for operators to be lifted, and what the type of the return value, if any, is for the lifted operator), so best consult Section 24.3.1. of the C# Language Specification. Note that Eric Lippert has admitted that the specification is a bit inconsistent with it's use of the term "lifted".

Uncategorized

A Culture of Innovation

Not so long ago the magazine Fast Company published a list of the most innovative companies. Business Week also seems to run periodic articles on corporate innovation as well [that's Marissa Mayer of Google on the cover]. And, of course, there is a World Innovation forum for conference-junkies. Lots of experts, like Harvard professor Clayton Christensen, say innovation is necessary for both large and small companies to prosper and many people have ideas about how the innovation process should be done. All this talk about innovation got me thinking about how do you go about encouraging internal innovation in a company. I mulled this over for a bit and here's what I came up with:

Think Big
Many people limit their thinking and because of this are limited in their achievements. It's relatively rare for an individual or an organisation to aim low yet somehow end up achieving great success, thus it's necessary to think big and aim high if you wish to be successful. Thinking big often involves embracing challenging problems that others avoid because the do not want to or cannot address them. After all, if it was easy everyone would do it and therefore reduce the strategic value of doing it in the first place.

Don't Bet Big
Innovation often conjures up the notion of big ideas produced by "big shots" that want to take big bets on a big future. You get the idea. The problem with the big bet approach is that you are limited to a small number of guesses and if you get it wrong it will go very badly. A series of smaller bets is a much better approach. Ideas should be prototyped, tested (scientifically if possible), reviewed, and iterated upon. This reduces the risk by getting early feedback and validation of the concept, the business model, and the technology used to develop the product/service. It also helps the stakeholders avoid the "we can't turn back now attitude" that happens when big bets/decisions are made that later turn out to be not so great but there is too much invested and too much political damage for stakeholders to advise that the wrong path has been followed.

Don't Innovate in Secret
"Innovation in secret" is where you don't tell anyone (your customers, your competitors, all of your employees) what you are doing and go off into the R&D cave and hopefully emerge with a killer product a few years later. Apple is famous for doing this and it works for them but it's an extremely risky proposition. There certainly will be a "stealth period" for some start-up companies and for both established and new companies you'll get a few years head start on your competition by doing secret innovation successfully, but a less risky route is to get feedback from select early-adopters and lift the veil of secrecy around your new product/service. Being shrouded in secrecy is more likely to lead to ill-informed decisions and makes it hard to follow the fail fast policy (see next point). The current trend of "crowdsourcing" is one way of harnessing the wisdom of crowds and getting fast feedback from early adopters on in-progress development.

Encourage Risk Taking, Accept Failures, Fail Fast
There is a general belief held by many decision makers that people don't get [fired|demoted|vilified|chastised] for being wrong, they get [fired|demoted|vilified|chastised] for being wrong and different. Thus, they believe it's not in their best interest to take seemingly-radical new directions. This is true in many corporations but for innovation to prosper you need to encourage some risk-taking and more importantly accept that failure is part of the process. Once the internal innovators in the company see that failure doesn't mean excommunication they are more likely to innovate. Of course, you want to try to fail fast - so the cost of failure to the company is minimised. This is done by following the second point - make small bets, and by identifying the major risk elements and tackling those elements as early as practically possible. For example, if your product deployment strategy critically depends on customers willingly installing a certain browser plugin, or customers willingly adopting a different behaviour for a particular task, you might want to mitigate this risk very early otherwise even perfect technical execution is going to be irrelevant.

Reward Good Ideas
People are less likely to devote time to breakthrough innovations if they know they will be rewarded only with a token gesture. If an idea returns a lucrative business outcome it's sensible to financially reward those who created the innovation. After all, people who are clever enough to contribute innovative ideas are smart enough to recognize imbalances in the contribution:compensation ratio and these people will be the first to leave if they feel under-appreciated or under-compensated.

Adopt a Meritocracy
Good ideas are good ideas. Don't let hierarchy, people's job title, length of service with the company, or people's level of remuneration be an issue when judging ideas. This motivates all of the company's employees to contribute to the innovation process which increases your likelihood of success because, although it's hard to believe, good ideas can come from anywhere. Personally, I find people who come from a scientific background better at doing this. The facts are gathered and analysed and rational decisions made in the absence of ego and other extraneous influences. Flat hierarchies also assist in this regard because there is less chance of HIPPOs killing projects. [HIPPOs=highest paid person's opinion]

Attitude is Important
Hire super-ambitious people, imaginative people, avaricious people, people who want to change the world, people who are passionate, people who have the X-factor (if you can find them). Sure stuff needs to get done and it's hard to co-ordinate a bunch of very-opinionated people, but for innovation to happen you need people like this. I very much like this list of personal qualities for entrepreneurial employees taken from Gifford Pinchot's book Intrapreneuring and brought to my attention by Mark Palmer, CEO of Streambase.

Next »