Search

Sunday, July 30, 2006

The CLR Nullable DCR works!!!!!

Cross posted from http://blogs.msdn.com/abhinaba/archive/2005/08/24/455765.aspx

CLR took a DCR some time back on how nullable types are implemented. See here and here to find out more about the DCR. I found from one of the internal DLs that the fix was already in the RTM bits.


I wrote a small piece of code which should work only with the DCR changes and kept it aside so once this DCR gets implemented I'd try it out. So each time I upgraded to a new build of VS/CLR I built/ran this code to see if it works. And it just did, with my todays upgrade to about 10 day old build in our lab. The new nullable type after becoming a basic runtime intrinsic just rocks. I have put in comment all the failures that used to happen previously with the same piece of code....


// this code works only with the latest bits of
// Visual Studio 2005 (C#2.0) and will fail to
// compile/run with older Beta2 bits

static
void Main(string[] args)
{
int
? val = 1;
int? nullval = null;


// this always worked
if (nullval == null
)
Console.WriteLine("It worked"
);

// this used to fail before and I think one of
// the biggest issue with the previous implementation
object
nullobj = nullval;
if(nullobj == null
)
Console.WriteLine("It worked"
);


// previously required
// box = Nullable.ToObject<int>(val); argh!!!!
object
box = val;


// If you do not need exceptional code
// (that's code that throws exception)
//
you needed to do int? unbox = Nullable.FromObject<int>(box);
int? unbox = (int
?)box;
if
(unbox == val)
Console.WriteLine("It worked again"
);


int intval = (int)box;
if
(intval == val.Value)
Console.WriteLine("attained Nullable Nirvana"
);


int x = 10;
object
y = x;
// Previously Exception!!! cast is not valid
int? z = (int
?)y;


IComparable c = val;
// Previously Exception!!! : object type cannot be
// converted to target type
if
(c.CompareTo(box) == 0)
Console.WriteLine("I have seen it all"
);


// compilation failure
IComparable<int
> ic = val;
if(ic.CompareTo((int
)box) == 0)
Console.WriteLine("Wow there is even more to see"
);
}


The output of the program is


It worked
It worked
It worked again
attained Nullable Nirvana
I have seen it all
Wow there is even more to see

Frame Arrangement in image strips used for animation

Cross posted from http://blogs.msdn.com/abhinaba/archive/2005/08/16/452080.aspx

Sometimes we get so used to things being the way they are we stop questioning them. We always have the perception in mind that individual frames of animated logo in a Bitmap strip is always horizontally arranged. I remember writing code to extract icons from a image lists that store individual frames of an animation sequence one after the other horizontally using something like


animationIcons = new Icon[bitmapStrip.Width / 16];
for (int
i = 0; i < m_animationIcons.Length; i++)
{
Rectangle rect =
new
Rectangle(i*16, 0, 16, 16);
Bitmap bmp = bitmapStrip.Clone(rect, bitmapStrip.PixelFormat);
animationIcons[i] = Icon.FromHandle(bmp.GetHicon());
}


Even winforms ImageList works on this assumption that the AddStrip method of the ImageCollection in the control has the images placed side-by-side. However this is not at all the optimal placement of images. Read it on Raymond Chen's blog .....

Function generator in C++

Cross-posted from http://blogs.msdn.com/abhinaba/archive/2005/08/12/450868.aspx

Some of us were just chatting about my previous post about function generators and we wondered about whether it can be done in C++ without using function pointers.... Most of my C++ knowledge has been rusted beyond repair but I thought even though its not possible to do directly, one can overload the ( ) operator to simulate this. So it should be possible to code so that the following is valid

FuncGen(Adder)(p1, p2)


Here the part in red semantically behaves like a function generator returning different functions based on the flag you pass. So here's some code in C++ that does it. Again I want to stress that this is not a function generator in C++, it just simulates something like it so that a statement like FuncGen(Adder)(p1, p2) will actually work....


#include <iostream>
#include
<string>
using namespace std;


enum FuncType
{
Adder,
Subtractor,
Multiplicator,
};


class CFunc
{
public
:
FuncType m_funcType;
template <typename
T>
T
operator
()(T p1, T p2)
{
if
(m_funcType == Adder)
return
FuncAdder(p1, p2);
else if
(m_funcType == Subtractor)
return
FuncSub(p1, p2);
else if
(m_funcType == Multiplicator)
return
FuncMult(p1, p2);
}


private:
template <typename
T>
T FuncAdder(T p1, T p2)
{
return
p1 + p2;
}
template <typename
T>
T FuncSub(T p1, T p2)
{
return
p1 - p2;
}
template <typename T>
T FuncMult(T p1, T p2)
{
return
p1 * p2;
}
};


CFunc cfunc;
CFunc& FuncGen(FuncType ftype)
{
cfunc.m_funcType = ftype;
return
cfunc;
};


int main(int argc, char* argv[])
{
int
p1 = 5, p2 = 1;
cout << FuncGen(Adder)(p1, p2) << endl;
cout << FuncGen(Subtractor)(p1, p2) << endl;
cout << FuncGen(Multiplicator)(p1, p2) << endl;
return
0;
}


Instead of using a global variable like cfunc I could have also created a object on the heap in FuncGen and later deleted it but since I have been coding in C# so long that I felt too lazy to write a delete statement.

My Experiments with continuation in C#

Cross-posted from http://blogs.msdn.com/abhinaba/archive/2005/08/11/450785.aspx

The blogs are buzzing with continuation support in C# 2.0 and what cool things can be done with it. http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons explains the concept of continuation extremely well. I also found Don Box's posting http://pluralsight.com/blogs/dbox/archive/2005/04/27/7780.aspx very interesting.


Traditionally in languages like C/C++ functions works off the stack. Each function call creates a new frame on the stack in which current context is stored (return address, current stack pointer) and then any arguments to the function is pushed in. The function also creates all its local variables on the stack and pops them off before the function returns. So when the function returns, all information regarding the functions execution is lost. So in case you call the function again it starts from the beginning.


However in continuation this is not what happens. Here the state of the function is preserved and when you call back on the function it starts off from where it left off. All the function locals are allocated on the heap so that their values are preserved when the function is called again. In C# we have a *very* restricted version of continuation using the yield return statement. Even though its restrictive it allows some very cool way of programming.


Here a sample of code where I have a container containing my friends names and I enumerate them.


public class MyContainer
{
string[] m_friends = { "Samrat", "Kaushik", "Rahul", "Abhinaba" };
public IEnumerator<string> GetEnumerator()
{
for (int index = 0; index < m_friends.Length; index++ )
yield return m_friends[index];
}
}


class Program
{
static void Main(string[] args)
{
MyContainer myContainer = new MyContainer();
foreach
(string str in myContainer)
Console.WriteLine(str);
}
}


You can have multiple enumerators too as in


public class CoolContainer
{
string[] m_friends = { "Samrat", "Kaushik", "Rahul", "Abhinaba" };
public IEnumerable<string> straight
{
get {
for (int index = 0; index < m_friends.Length; index++ )
yield return m_friends[index];
}
}
public IEnumerable<string> Reverse
{
get{
for (int index = m_friends.Length - 1; index >= 0; index--)
yield return m_friends[index];
}
}
}


class Program
{
static void Main(string[] args)
{
CoolContainer cc = new CoolContainer();

foreach
(string str in cc.Reverse)
Console.WriteLine(str);

Console.WriteLine("----------------");

foreach
(string str in cc.straight)
Console.WriteLine(str);
}
}


Seeing all these work I got carried away and tried to do the enumeration without the foreach as in



IEnumerator<string> enumerator = myContainer.GetEnumerator();



enumerator.MoveNext();


Console.WriteLine(enumerator.Current);


enumerator.MoveNext();


Console.WriteLine(enumerator.Current);


enumerator.Reset();



enumerator.MoveNext();


Console.WriteLine(enumerator.Current);



My idea was that after the call to Reset internally I would be able to reach the first element in the list as the index variable will be reset. That’s where I got the surprise in the form of a NotSupportedException in the call to Reset. I send emails to the CSharp user group and found out that its indeed not supported and you need to create new enumerator to go back or if the enumerator once runs till end (i.e. one return is executed) then you’ll automatically get the reset you wanted. This means that iterating twice or more using the same iterator works as in



MyContainer myContainer = new MyContainer();
foreach
(string str in myContainer)
Console.WriteLine(str);
foreach (string str in myContainer)


Console.WriteLine(str);

Anonymous methods and closures in C#

Cross-posted from http://blogs.msdn.com/abhinaba/archive/2005/08/08/448939.aspx

Anonymous Method

One of the new features in C#2.0 being shipped in with Whidbey is anonymous methods. Though this at first glance looks like an easy way of creating delegates, where instead of having to create a new function which the delegate will call you can pass the code inline.

Before C#2.0

class MyClass
{
delegate void MyDelegate
();
static public void
Function()
{
Console.WriteLine("I'm called"
);
}

static void Main()
{
MyDelegate writeMessage = new MyDelegate
(Function);
writeMessage();
}
}


With C#2.0 and anonymous methods: the Function is eliminated and the same piece of code can be written more elegantly as follows


class MyClass
{
delegate void MyDelegate();
static void Main()
{
MyDelegate writeMessage = delegate ()
{
Console.WriteLine("I'm called"
);
};
writeMessage();
}
}


For more details on Anonymous methods check out http://msdn.microsoft.com/msdnmag/issues/04/05/c20/default.aspx.


However, there is more to it than just getting a short hand way of writing code. With anonymous methods you can now do a lot of things in C# which are commonly done in Functional languages. Consider the code below which is actually a function generator.


class Program
{
delegate void MyDelegate
<T>(T t);
enum
FunctionType
{
WithPrefix,
WithoutPrefix
}
static MyDelegate<T> FunctionGenerator<T>(FunctionType
fType)
{
int i = 0;

if (fType == FunctionType
.WithPrefix)
{
return delegate(T t)
{
Console.WriteLine(i.ToString() + ": "
+ t.ToString());
i++;

};
}
else
{
return delegate
(T t)
{
Console.WriteLine(
t.ToString());
};
}
}


static void Main(string[] args)
{
MyDelegate<int> mdWith = FunctionGenerator<int>(FunctionType
.WithPrefix);
mdWith(5);
mdWith(5);

MyDelegate<string> mdWithout = FunctionGenerator<string>(FunctionType
.WithoutPrefix);
mdWithout(
"Hello"
);
}
}


The output is
0 : 5
1 : 5
Hello


As in the above piece of code you can create Function Generator that actually return different implementations based on requirement. For another interesting sample see Don Box's blog http://pluralsight.com/blogs/dbox/archive/2005/04/17/7467.aspx


Closure


For any languages which allow passing around functions as arguments or functions returning another function the Closure abstraction is very important. For more info on Closure see http://en.wikipedia.org/wiki/Closure_(computer_science. C#2.0 supports closure by the use of anonymous methods.


Closure is a function along with its lexical environment (available variables and their values) when the function is created.


int i = 10;
return delegate(T t)
{
Console.WriteLine(i.ToString() + ": "
+ t.ToString());
};


Since the variable i was available with the value 0 when the Anonymous method was created, inside the method, i will be available with the same value when the method is called via the delegate.


From the definition of Closure it can be inferred that Closure remembers the values of the variables during its creation. However in C# the outer local variable (i in this case) is shared with the anonymous method by creating it on the heap. This means any change to it in the anonymous method changes the original value and when the method is called the second time it gets the modified value of i as 1 (see second line of output). This leads many to argue that anonymous method is not actually a Closure as by its definition the value of a variable at the time of creation of the Closure should be remembered and not modifiable.


Check out the link http://blogs.msdn.com/brada/archive/2004/08/03/207164.aspx on how the implementation of Anonymous methods in C# have led to interesting issues.

marking required fields on forms/UI
Cross-posted from http://blogs.msdn.com/abhinaba/archive/2005/06/26/432832.aspx
How do you communicate to users which fields on a UI is required and which is optional? This was the questions I was trying to answer while implmenting the Team Build Type creation wizard. Though there exists some common conventions in Web forms like marking the fields with asterix and putting something like "Fields marked with an asterix * are required" somewhere on top, there seems to exist no convention to do this on Windows user interfaces.
In team system the work item tracking UI does this by making the background color of the required fields with the same color as tooltip (yellow) and then as soon as the user types in some thing in them the color changes back to window backgorund color (white). So the user can quckly review the form and can locate fields that are left to be filled as they are marked with a different color (yellow).



I liked this idea a lot and wanted to do the same thing with our wizard and Start build forms. But could'nt get that approved by the User Experience team becuase they think that on wizards the visual cue should come from the enabling of the Next button. The idea is that once the user has filled in all the required fields in the page Next should get enabled so that he can move to the next page. I think this works well only when the number of controls on the Wizard page is less, other wise the user will keep trying to guess why the next button in not getting enabled. Since wizard guideline clearly calls out against crowding too many things in one page, I guess this is fine but still think we should move towards a common guideline on marking required fields and I think the background color change is a fine way of doing just that.

Command line tool syntax

Cross-posted from http://blogs.msdn.com/abhinaba/archive/2005/01/20/357058.aspx

Command line interface (CUI) designs for many of the tools found with VS or in Windows were to include a bunch of individual commands or exe with options or flags.

To get a directory listing: dir <options> as in dir c:\temp /w
To create a directory: md c:\temp\foo
To delete a directory: rd /s c:\temp\foo

So even though all the tasks pertain to directory or path handling , you need to know three command to do the task. This design is slowly changing to the format of command <action> [</options:attributes>]

For example if we change the above commands to this format with the common command called dir, we will be getting
To get a directory listing: DIR list c:\temp /w
To create a directory: DIR make c:\temp\foo
To delete a directory: DIR rem c:\temp\foo /s

So effectively user learning is reduced. One can argue that he still needs to remember the names of the actions. But in the previous case he needs to remember rd, md, dir. Now he knows everything to do with path handling is to be done with DIR. So he can run DIR /? to get the list of actions and then do a DIR list /? to know the options for listing. The other advantage is namespace pollution in terms of the names of the executables also reduces.

This new format has also been adopted in the VS as in the source control tool. So to get the listing of all workspaces on MyServer you run the command
h.exe workspaces /s:MyServer
To create a new workspace you run the command
h.exe workspace /new MySpace /s:abhinab-test
I guess going forward we will see more and more of the standard OS commands also taking up this format. A very common example is the NET command
Error Messages

Cross posted from http://blogs.msdn.com/abhinaba/archive/2005/01/12/351201.aspx

Frequently we are presented with error message pop-ups with messages like "Unable to open file". Error messages are popped up when something has gone wrong. If SW cannot convey to the user what went wrong and what he can try to fix the problem, it might as well not show the error message at all.
So all errors messages must have three components
  • Notification
  • Explanation
  • Solution
A good example for a Team Build scenario would be
Unable to connect to the build machine "BuildServer01"
Make sure that the machine is connected to the network and the TeamBuild Service is running on it.
So all error messages that have one sentence in them are most probably not as helpful as it states what happened and not what can be done to rectify it.
Another important thing to note is that the user is never to be blamed for any error. If the action he did was dumb then we are at fault that we did not restrict him from committing a dumb action.

Cross-posted from http://blogs.msdn.com/abhinaba/archive/2004/11/16/258046.aspx

I always tried to figure out that in spite of the fact that India will become one of the largest PC markets in the future and that India SW engineers are everywhere, why is there no mainstream software in Indian languages. Yea there is Windows Hindi, and I read somewhere that Windows Bengali is also coming up, but thats after years of existance of Windows in other not so prevalent languages. I always got the answer that this is mainly due to SW piracy. Its so prevalent here that almost no one pays for software and hence the SW companies do not have revenue motive to localize their software for India. A further study revealed that 63% of al PCs in India ship with pirated Windows!!!! A person who is ready to use a pirated OS, will surely not pay for any other software he installs on that box. So this can lead to millions of dollars lost in revenue for the SW companies.

Its so bad here that frankly till date I have rarely seen a home user using a legitimate copy of Windows. Even when I have seen that, it was in branded PCs which came pre-installed with the OS. The moment I congratulated someone for using a legitimate OS, within a minute he figures out that he was made to pay for the OS by the PC vendor, and he felt bad that he could have got the pc for less if he had a way for not opting for the OS.

This issue is not only with home users, its every where, its in cyber cafe's, in SOHO, even in mid size organization and colleges. PC vendors are adding fuel to fire by shipping PCs with Linux pre-inslalled on them. This serves as a simple solution to buy a branded PC at a lower cost. People buy this PC, goes home and installs Windows from pirated CDs which cost them around Rs.100, thats a little more than $2. So now you have a branded PC running Windows sans the price.

Many have suggested that low cost software is a solution to this. I absolutely do not agree with this. It may be a part of a solution but not the solution in itself. SW piracy has become so prevalent that no one feels like paying for it. You are considered a fool if you pay. What is required is a change in the way of thinking, user education and pride of ownership. People need to know that its equivalent to stealing, and is a punishable offense. This is a bad thought though, with 63% of all PCs shipping with pirated OS, it brings most my friends and relatives who own a PC in this category...

Friday, July 28, 2006

The CEO of Microsoft Corporation, Steve Balmer is visiting Hyderabad on the 15th (next Monday). There's a lot of excitement around this. He is supposed to inaugurate a part of the new Microsoft Campus and also to lay foundation stone for the second phase.

Hyderabad is very proud to house the MS IDC, a race it won by defeating several other cities. This visit is raising lot of rumors and some sites have gone as far as to predict that the new center will slowly grow and employ 5000 developers and will be the largest outside US. Check out http://economictimes.indiatimes.com/articleshow/915404.cms. This appears to be a very distant reality. Personally I’m eager to hear what he has to say.

MS was working out of rented facilities that spread across multiple floors in different buildings. Since these building are part of Software Parks, some additional benefits come with it. You get banks, ATMs, florists, travel agents, restaurants all at the same place.

However, like most people I prefer the company having its own campus. You get a feel of unity and get to meet a lot more people from your own company. Casual chats over a cup of coffee can give amazing insight into a different technology domain which the other guy sharing your table works in. I just can’t wait to get into the new building once it start functioning…

Monday, August 08, 2005

I joined Microsoft and that automatically resulted in me moving to C# from C++. So I kind of stopped blogging here and moved on to http://blogs.msdn.com/abhinaba/. I thought may be I'll keep my non-tech stuff to this blog and use the one on MSDN for all the technical stuff, but two blogs are kind of overkill so I had almost no posting here for 10 months. I guess thats about to change now.


So hows Hyderabad? Check out my friends thought from http://thor.prohosting.com/amitc/mt/archives/2005/08/the_hi-tech_lif.html

Tuesday, August 10, 2004

I figured out that though my web-site is that of a programmer it has very little stuff to do with programming. So I decided that I'm going to change this!!!!

So my site http://www.geocities.com/basuabhinaba/ is updated with a Code link on the top. I plan to update this regularly with interesting code snippets and other programming stuff. I have already put up some stuff. Lets see how it goes.

Every time I update my site I feel I need to go and get a domain name registered. I am too lethargic to actually do this. Lets see how this goes through!!!

Saturday, July 24, 2004

I have heard of the famous urban legend that NASA spent millions of dollars to invent a pen that could be used to write in Space. In space there is no gravity and so the common ink filled pen will not work because gravity will not pull down the ink towards the nib. When NASA was spending this money on the pen research, Russia went ahead and used pencil instead. It served the same purpose at no extra cost!!!

I got it from a book that the site
Fisher Space Pen Co. - Engineered for Better Writing
is of the company that invented the pen for NASA.

The prices on this site says $130 for a pen. That is approximately Rs.5850 in Indian currency. This will be more than the average monthly family income for most Indian household. Even by metropolitan standards that is almost equal to half the salary for a lot of people.

Friday, July 16, 2004

I friend asked me this question.

Write a C++ program that prints "Hello" hundred times without using any loop or recursion statements and obviously without writing the printing statement hundred times.

And the solution is



#include
using namespace std;

class Show
{
public:
show(){cout <<"Hello" << endl;};
};

int main()
{
Show s[100];
}



I just do not know why someone will ever need this but found it very amuzing. He even went as far as to optimize it by adding the same cout << "Hello" to the destructor and only creating 50 objects instead of 100!!!!!!!

Wednesday, July 14, 2004

C++ - Stop people deriving from your class

One of my friends was facing a problem while trying to write a class B so that no one would be able to inherit from it. He used code as below.



class B; // forward declaration

class Prot // this class is used to stop the inheritance
{
public:
friend class B; // allow only B access to ctors
private:
Prot(){}; // make all ctors private
Prot(const Prot &p){};
};

// class that cannot be inherited from
class B: public Prot // inherit from prot. Since B is friend of Prot it'll work
{
public:
B();
int a;
};

class D : public B
{
public:
int d;
};

D d; // this should fail




However D was still able to inherit from B. What he missed was using virtual inheritance for inheriting from Prot as follows


class B: public virtual Prot // inherit from prot
{
// ...
}

this lead to the bug. Without virtual inheritance the call does not go via the vtable and D is able to access Prot's ctor as it is merged with that of B.

Tuesday, July 13, 2004

We knew MS primarily as a secretive organization who is always fighting off Open Source and GNU. But these days they have really gone open thoughts if not open source. Most of them including architects like Herb Sutter have blogs on the net where they speak there hearts out (or is it??)

Check out the following blogs

Brandon Bray Blog
Herb Sutter

Brandon has a nice little piece on the justification of introducing the ^ into C++.
Amazing blog. I don't know from where she(??) gets these links. http://www.stormwerks.com/linked/

Monday, July 12, 2004

I use the CodeProject a lot. One of the maintainers of the site happens to be an Indian who has a interesting blog at http://blog.voidnish.com/

His site http://www.voidnish.com/ is also kinda interesting. May be I'll go and get a domain name for myself one day. Lets see.....

Thursday, July 08, 2004

Give it back

Programers face a slew of problems each day. We either solve it ourself or search the net for resources that better equip us to solve them. The resources could be reference material, books, articles, code snippets or even full fledged application whose source have been given out by a developer.

Some of us take time to thank the kind soul behind the resource via email, but most of use just take it for granted that they are just available. Some even look down upon them considering them as show-offs but still use there material anyway!!!!

But is it not our duty to also give back, from where we are getting so much for so less (actually free). I think it is the moral duty for all developer to give back something to the online developer community. You can always try sites like CodeProject.com or CodeGuru.com.