Search

Monday, February 25, 2008

Coolest reception

 

chauffeur waiting for Google folks at the airport

Rental car chauffeurs waiting for some software company employees. No marks for guessing the name of the company :)

Wednesday, February 20, 2008

International Mother Language Day is back and being celebrated with a lunar eclipse

Interview - Delhi

For starters it doesn't include C++ or C#, even though your mom codes in it :) ...

A lot of people speaking English natively forget the importance of mother language due to its predominance. They take their language for granted. However, each year a bunch of languages become extinct, the latest being Eyak, which got extinct exactly a month ago with the death of Marie Smith Jones the last native Eyak speaking person.

To me this day (21st Feb) is even more special because on this day in 1952 people in Bangladesh laid down their lives while demanding the right to use their own (and mine) mother language, Bangla.

I believe that if we don't actively try to preserve our mother language they will slowly become extinct. One of the most important things to preserve a language is to ensure that they are better covered by technology. Until XP complex script handling was not enabled by default. This resulted in Bangla and other Indic language to be rendered completely wrong on XP. This was a serious deterrent to use Bangla on Windows. I used to have Bangla signature in my email and got countless replies indicating the spelling is wrong. I always replied back to them about how to turn the complex script handling on. Things are changing rapidly, Vista has this on by default and with better keyboard and font support I'm sure using Bangla on Computers will become really easy.

Tuesday, February 05, 2008

Linked on the msdn forum for all the wrong reasons

Flowers Rennaisance hotel - Mumbai

Someone saw a message in their Team Foundation Server history which was "Edited by God" and asked how is this possible on the msdn forum. Someone actual read my blog (or some other's but I tend to believe mine 'cause I'm linked in that page)  which shows exactly how to do that. So now I have a poor-joke (PJ) of mine being featured in msdn :)

Sunday, February 03, 2008

Rain in Lahari resort - hyderabad

For the last couple of days a vast majority of the movie that I'm seeing is somehow landing in Africa. Since I didn't choose any of them (Amit did), it wasn't a conscious decision. Example include The Interpreter, Blood Diamond, Duma.

In all of these movies African music is used in the background, and I've began to like them a lot. I have no idea about the tribe/nationality of these but the sound is just enchanting. Any idea where I can get some good original African music on the web? Buying is also an option if Indian stores/sites have them (which I heavily doubt).

Update: A comprehensive list from someone who obviously knows a lot more about this, link

Tuesday, January 22, 2008

Banana leaves - hyderabad

Sometime back I posted about variable parameters in Ruby. C# also supports methods that accepts variable number of arguments (e.g. Console.Writeline). In this post I'll try to cover what happens in the background. This is a long one and so bear with me :)

Consider the following two methods. Both prints out each argument passed to it. However, the first accepts variable arguments using the params keyword.

static void Print1(params int[] args)
{
foreach (int arg in args)
{
Console.WriteLine(arg);
}
}

static void Print2(int[] args)
{
foreach (int arg in args)
{
Console.WriteLine(arg);
}
}

The above methods can be called as follows

Print1(42, 84, 126); // variable argument passing
int[] a = new int[] { 42, 84, 126 };
Print2(a); // called with an array

Obviously in the case above, using variable number of parameters is easier.

If we see the generated IL for Print1 and Print2 using ILDASM or Reflector and then do a diff, we will get the following diff

.method private hidebysig static void Print2(object[] args) cil managed
.method private hidebysig static void Print1(object[] args) cil managed
{

.param [1]
.custom instance void [mscorlib]System.ParamArrayAttribute::.ctor()

.maxstack 2
.locals init (
[0] object arg,
[1] object[] CS$6$0000,
[2] int32 CS$7$0001,
[3] bool CS$4$0002)
L_0000: nop
L_0001: nop
L_0002: ldarg.0
L_0003: stloc.1
L_0004: ldc.i4.0
L_0005: stloc.2
L_0006: br.s L_0019
L_0008: ldloc.1
L_0009: ldloc.2
L_000a: ldelem.ref
L_000b: stloc.0
L_000c: nop
L_000d: ldloc.0
L_000e: call void [mscorlib]System.Console::WriteLine(object)
L_0013: nop
L_0014: nop
L_0015: ldloc.2
L_0016: ldc.i4.1
L_0017: add
L_0018: stloc.2
L_0019: ldloc.2
L_001a: ldloc.1
L_001b: ldlen
L_001c: conv.i4
L_001d: clt
L_001f: stloc.3
L_0020: ldloc.3
L_0021: brtrue.s L_0008
L_0023: ret
}

Only the lines in Green are additional in Print1 (which takes variable arguments) and otherwise both methods looks identical. In this context .param[1*] indicates that the first parameter of Print1 (args) is the variable argument. The ParamArrayAttribute is applied to the method to indicate that the method allows variable number of arguments.


Effectively all of the above means that the callee is not really bothered with being invoked with variable number of arguments. It receives an array parameter as it would even without the param keyword usage. The only difference is that the method is decorated with the some directive and attribute when param is used. Now it's the caller-code compiler's duty to read this attribute and generate the correct code so that variable number of parameters are put into a array and Print1 is called with that.

The generated IL for the call Print1(42, 84, 126); is as follows...

.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 3
.locals init (
[0] int32[] CS$0$0000)
L_0000: nop
L_0001: ldc.i4.3 ; <= Array of size 3 is created, int32[3]
L_0002: newarr int32 ; <=
L_0007: stloc.0 ; <= the array is stored in the var CS$0$0000
L_0008: ldloc.0
L_0009: ldc.i4.0 ; push 0
L_000a: ldc.i4.s 0x2a ; push 42
L_000c: stelem.i4 ; this makes 42 to be stored at index 0 **
L_000d: ldloc.0
L_000e: ldc.i4.1
L_000f: ldc.i4.s 0x54
L_0011: stelem.i4 ; similarly as above stores 84 at index 1
L_0012: ldloc.0
L_0013: ldc.i4.2
L_0014: ldc.i4.s 0x7e
L_0016: stelem.i4 ; stores 126 at index 2
L_0017: ldloc.0
L_0018: call void VariableArgs.Program::Print1(int32[]) ; call Print1 with array
L_001d: nop
L_001e: ret
}

This shows that for the call an array is created and all the parameters are placed in it. Then Print1 is called with that array.

Footnote:
*interestingly it starts at 1 and not 0 because 0 is used for the return value.
**stelem takes the stack [..arrayindexvalue] and replaces the value in array at index with value

Monday, January 14, 2008

The differences between int[,] and int[][]


Mumbai roadside drinks

A friend asked me the differences between the two. Here goes the answer

int[,]

This represents a two dimensional rectangular array. Let's take the following array definition

int[,] ar = new int[3, 3] { { 0, 1, 2}, 
{ 3, 4, 5},
{ 6, 7, 8}};

The array actually looks like the following



Which as we can see is rectangular. This kind of array is required when for every items represented in the rows there's exactly the same number of items represented in the column. E.g. a board game like chess.


int[][]


This is defined as array of arrays or as jagged arrays. They are created as follows

int[][] ar2 = new int[3][];
ar2[0] = new int[] { 0, 1, 2 };
ar2[1] = new int[] { 3, 4 };
ar2[2] = new int[] { 5, 6, 7, 8 };

The array looks like


Capture


Here the number columns is not the same for each row. A good example of this kind of usage is when we have a array of polygons where each row contains the coordinates of the vertices of the polygon. Since each polygon has different number of vertices (square, triangle, ...) this data-structure is useful in defining it.


Since it's jagged it has to be referenced carefully.

Console.WriteLine(ar2[0][2]); // Prints 2
Console.WriteLine(ar2[1][2]); // Crashes as row 1 has only 2 columns

The jagged array can be padded on the right to convert it to a rectangular array, but this will result in a lot of space wastage. In case of the jagged array the usage of space is sizeof(int) * 9 but if we pad it we will use sizeof(int) * max (column). This additional space can be significant.


Note:


int and 2D arrays were used only as example. This applied equally well to other data-types and higher dimensions.

Sunday, January 13, 2008

Expanding and compressing in Ruby Method calls


2007_0520_184605

One of the things I didn't like in Ruby at all is the support for method overloading. You have no ways to support it in a straight forward way other than to define a single method that takes a variable number of arguments.

def foo(*f)
f.each { |a|
puts a
}
end

foo("Hello", "world")

What the above does is that it converts the multiple parameters into a single array and passes it to the method call. I think this is really bad because method overloading is a very basic requirement.


However, Ruby seemed to support another really weird feature of expanding arrays in method calls. What this means is that if a method accepts a number of parameters and it's called with an array then the array is expanded such that the i'th element in the array is passed as the i'th argument.

def bar(name, address, age)
puts (name, address, age)
end

details = ["Abhinaba", "Hyderabad, India", 42]
bar(*details)

So details[0] is passed to the name parameter and details[1] is passed as address, and so on

Learn a new dynamic or functional language every year


2007_0501_091707

Specially for folks using the C* languages (C/C++/C#) and Java it's very important to learn dynamic/functional languages.

There are three reasons.

  1. With time we will see more and more high level dynamic languages and at the same time many languages like C# will take up dynamic/functional language attributes and hence it's good to be prepared
  2. It'll give a fresh perspective to do the mundane day to day coding. Lambda's in C# won't look alien any more :)
  3. It's fun and will help you survive going through gazillion bulleted lists like this ..

I think the fun part is the most important.

``I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.''

Alan J. Perlis (April 1, 1922-February 7, 1990)

Monday, December 31, 2007

Open a beer bottle with paper

 

If I knew this during my college years my teeth would've been in better shape now :)

For more life hacks head here.

Wednesday, December 19, 2007

Giving up on Ubuntu

Whidbey_2005_0409_131710

I have an old hp laptop (1.3 GHz, 512 mb RAM) lying around on which I'm trying to install Ubuntu. There's no reason for it, but I had just backed up all stuff on it to another machine and I thought I'll give Ubuntu a spin.

I downloaded Ubuntu 7.10 burned it onto a CD and booted it up. After that the experience so far has been real bad. I ran into all sorts of issue. Listed some of them below

  1. Initially I tried various languages in the installation screen, complex script was completely broken. I understand if an installer doesn't support Bengali or Hindi, but in that case the option shouldn't be in the screen, specially when it's not even readable. On top of it language switch wasn't painting the screen correctly
  2. Installer went on broadcasting some sort of weird garbled sound (I guess garbled due to CPU stress)
  3. It booted up into a brown screen without any option to do anything. I waited couple of hours and figured out something is wrong and rebooted again into some safe mode
  4. After a long time it did come up but the UI was sluggish to the point of not working
  5. I clicked on the install icon and nothing happened for a long time.
  6. Now I'm stairing at a fancy screen where the cursor is frozen and the CD is making sounds as if it wants to join F1 racing.

I know the Linux fanatics will sham me as a fool and point me to all sorts of hacks and stuff I can do. The problem is that I'm really not interested in tinkering with installation, I'm used to them just work. I'm not an admin and couldn't care less about these things. For me getting it up and running so that I can do the stuff I wanted to do is more important.

Right now I'm at the point of giving up and moving to some other Linux distro. I'm out of touch with Linux for a long time (~6 years) and I guess I need to look around. Hopefully Red-Hat and Mandrake will work for me.

Thursday, December 13, 2007

Bar Charts on the console

Golconda fort arches

I work on the UI action recorder and it has a strict performance requirement. The tool dumps the time it takes to record each action in it's log and that is compared against the maximum allowed value (otherwise the system will seem sluggish). To do this obviously we need fancy charts, as everyone likes them, other than of course the alpha-geeks :).

However, I like the console chart. Way back my mom used to work on Main-frames that ran COBOL on them and dumped out business data on paper at the end of the day. These reports had these printed bar charts.

I wrote a small ruby script to dump these charts on the console. The output looks like

D:\MyStuff\Code\Ruby>perf c:\logs\Recorder_20071118_144855.843.log
c:/logs/Recorder_20071118_144855.843.log ===============================>
640 ********************************************************************************
0 *
109 *************
0 *
46 *****
0 *


Serves the same purpose as their fancier counterpart but manages to look uber geeky.

Support for range in programming languages

DSCF2530

The .NET platform and the languages on top of it have limited or no support for range of values. Data ranges are one of the most common data-types and somehow it's not there. Funnily most programmers do not even seem to miss it (unless of course if you have used Ruby).

How would you specify a valid range of age and validate user data against it? If you know the maximum and minimum values, at max you'd define a MaxAge and MinAge consts and strew the code with if(age < MinAge|| age >MaxAge). Or maybe you'll define a class to encapsulate this and add a IsValid method.

However, in Ruby, Range is a standard DataType like say string. To do the above processing you'd do

age = 1..120

print age.include?(50)
print age.include?(130)


print age === (50) # more easier way to do include? test using the === operator


So intuitively you create a range using start..stop.


Creating a range of data is also very simple. Say you want to generate the column numbers for an excel sheet, you'd do the following

column = 'A'..'ZZ'

column.to_a # creates an array of all the values

column.each {|v| puts "#{v}\n"}

Similarly ranges can be easily created for any class by implementing some special methods. On ruby the support of Range is in the compiler and makes the code very easy to develop and intuitive.


>>Cross posted here

Wednesday, December 05, 2007

Fun Windows Home Server site

2006_1101_200024

Windows Home Server team has a nice light-hearted site up at http://www.stayathomeserver.com/. All of it was funny, until I reached the page http://www.stayathomeserver.com/book.aspx. It says "daddy wants to give mommy a special gift.... So he buys a stay-at-home server".  That's not funny, "Wife Acceptance Factor" would be reflecting nitrogen freezing point for a home server.

You can sneak one in, understate the price and show all the image streaming to kinda buy acceptance, but a gift, no way :)

Saturday, December 01, 2007

Choose your company name well

 

Picture 057

Sometime back Hutch phone in India got bought over by the international phone giant vodafone. They re-branded Hutch in India to Vodafone.

Now when I call up home and the phone is busy I get a recorded message in Bengali which means "The Vodafone number you're trying to call is busy". All that is good but the problem is that vodafone in Bengali exactly means foolish phone. So I just hang up and wait for the foolish-phone to get free.

Friday, November 30, 2007

Ravenous Bugblatter beast on Indian roads

From the HitchHiker's Guide to the Galaxy.

"The Ravenous Bugblatter Beast of Traal is a creature that hails from the planet of Traal, and will eat anything. If you are to encounter one, the Guide tells you that it's impossible to slay, so you should wrap a towel around your head. This creature is so mind-bogglingly stupid that it assumes that if you can't see it, then it can't see you."

I felt like one while on a road-trip to Visakhapatnam and surely you'll feel like one on Indian roads. We were going at high speed and suddenly we see someone crossing the highway. We honked hard and the person simply looked down. So the idea is that, if he can't see you, then you don't exist. Or maybe they were using the SEP field technology.

In the following video watch the first person crossing the road and next a cyclist goes in the wrong direction as we wiz past at 120kmph (75 miles/hour).

Newbie Question: How do I figure out the inheritance chain of a type

Redmond_2005_0417_010447

I got this question from someone just starting out on the .NET platform. He is used to hit F12 (go to definition) on types and then figure out the inheritance chain. However, he couldn't do that say on a number (int) or array.

The solution is to write a simple recursive routine as follows

static void Dump(Type t)
{
if (t != null)
{
Dump(t.BaseType);
Console.WriteLine(t.ToString());
}
}

The routine can be called as follows

Dump(typeof(int));
Dump("abc".GetType());
Dump(1.GetType());
Dump(typeof(EventAttributes));
No marks for guessing the output though :)

Wednesday, November 28, 2007

Woohoo - Rosario November CTP is out...

2006_0311_123604

...and I can finally talk about what I'm working on for the last so many months.

First things first, for more information on Microsoft Visual Studio Team System code name "Rosario" November CTP release head on to Jeff Beehler's blog

A small bullet in the list of features is Manual Test execution. What it means is that you can now record you manual tests and play them back. Yes, it means you have a UI record and playback feature in the Manual Test Runner!! It's not a full fledged UI automation solution for now. It is mainly targeted to speed up manual testing so that the manual tester can zip past the part which she is not interested in testing. E.g. the manual tester can record the login, purchase pages so that she can play them to directly land in the final checkout page and do manual actions/validations on it.

The solution works for web-UI (IE pages) and also has very limited support for Win32 applications.

I work as a part of the team that develops the record and playback (RnP) framework. It's been an excruciating working on a great technology but not being able to publicly talk about it. Thankfully that time has ended :)

How do you name your computer

2006_1101_200024

Windows gives examples of "Kitchen Computer" or "Mary's Computer" for setting the name of a computer (Computer Name tab in System Properties). But I'm sure that most people don't name their computers that way and show off a bit of creativity in it.

Previously I used to use names from Asterix like GetAFix for my main dev box. Now I exclusively use names from Hitchhiker's Guide to the Galaxy. Some of the machines I use are named as below

  1. traal: My test box
  2. Krikkit: My dev box
  3. Vogon: A old vintage machine I have at work which I use to test some perf scenarios (Vista on 512mb RAM :^) )
  4. Hooloovoo : My personal laptop
  5. Bugblatter: Another laptop

What name do you use?

Tuesday, November 20, 2007

True object oriented language

 

DSCF2530

Today I was spreading the goodness of Ruby and why I love it so much (and you can expect multiple posts on it). SmallTalk programmers can sneer at me, but hey I wasn't even born when SmallTalk came into being and hence I can be pardoned for pretending that Ruby invented this :)

Languages like Ruby are "truly" object oriented. So even a number like 2 is an instance of the FixNum class. So the following is valid Ruby code which returns the absolute value of the number.

-12345.abs

Taking this to an extreme is the iteration syntax. In C# to write something in a loop "n" time I'd be needed to get into for/foreach syntax, however in Ruby I can do the following

5.times { puts "Hello"}

Which prints Hello 5 times.


However, I actually lied about having to use for/foreach statement in C#. With the new extension-method/lambda goodness we can very well achieve something close in C#.


For that first we create the following extension method

public static class Extensions
{
public static void times(this int n, Action a)
{
for (int i = 0; i < n; i++)
{
a();
}
}
}

Then we can call "times" on an int as easily (well almost as I still need some lambda ugliness).

5.times(() => Console.WriteLine("Hello"));
// Or
6.times(delegate { Console.WriteLine("Hello"); });

All programming languages evolve towards Lisp

 

2007_01_28 120

In an internal DL people were debating what all should be included in the next version of C#. One of the things I suggested turned into an interesting thread.

Abhinaba: Add if as expression (like in Ruby) so that I can do the following

var ageGroup = if age < 2
                   "Infant"
               else if age < 19
                   "Teen";

SomeOne: Can't we do

var ageGroup = ((age < 2) ? "Infant" : ((age < 19) ? "Teen" : String.Empty));

Abhinaba: We can but put 4 more cases and it’ll start looking like Lisp :) with all the parenthesis.


SomeTwo: All programming languages evolve towards Lisp.


Yeah, right!!!