Monday, December 29, 2008

CNN headlines

This is what CNN front page looks like today.



And this is the article to which it links.



Funny how the wording of the title changed enroute, huh?

Israel

"The tale of Israel can be very much compared to someone who was beaten, tortured, molested and raped as a boy by his family members. You don't expect someone like that to grow up to be "normal". The founding of the state of Israel right after the holocaust was a big mistake. The boy grew up, learned martial arts, amassed weapons and became extremely aggressive towards his surroundings, seeing the ghosts of his tormentors in every face that he sees around him. Now he is channeling his childhood pain towards inflicting the same pain upon others. Desensitized to human sufferings, he is now capable of enormous acts of cruelty."

http://www.reddit.com/r/worldnews/comments/7m6m4/today_i_end_my_support_of_israel/647s

...in response to...

http://www.dailykos.com/storyonly/2008/12/28/114432/83/489/677860

I kid you not...

"Sometimes these dollars go to projects that have little or nothing to do with the public good. Things like fruit fly research in Paris, France. I kid you not," Ms Palin said.

http://www.independent.co.uk/news/science/scientific-illiteracy-all-the-rage-among-the-glitterati-1212406.html

Biology is clearly not on the list of graduation requirements on whatever "school" this woman went to... I am just wondering - who ARE these people in Alaska? This whole thing starts looking very much like Russia in 1920.

The reason to learn math...

http://abstrusegoose.com/96

I am so using it on my kids!

Sunday, December 28, 2008

SQL nullable data items and LINQ

While working on Malevich - my new code review program, - I was hit by a runtime error when doing LINQ operation on a table that contained null datetime items. In C#, DateTime is a structure - not a class - and therefore can not be null.

Classes in C# are always allocated in the heap, and the variable that holds class object is really a pointer, whereas structures can be allocated on stack (just like classes and structures in C++), and variable that references a structure is really the memory representing this structure.

If C# had a sizeof operator, the sizeof of a variable containing class instance would always be a sizeof of a pointer - 4 or 8 bytes, - whereas a sizeof of a variable containing a structure would be the number of bytes that it takes to store this structure in memory.

Which is why string x = null is valid, but DateTime x = null is not. You can, however, explicitly create a "pointer" to DateTime (or any structure or primitive data type) by using the question mark after the type, for example, DateTime? x = null. This is called a "nullable" data type.

It turns out that the logic in Visual Studio that imports the database model (dbml) does not properly recognize nullable data in SQL - it generates not nullable prototypes for it.

For most common data items it is not an issue. Strings are class instances, and so they can be null in C#. It is not usual I suppose to store nullable numeric types - it would likely be more expensive to store the fact that it is or is not null rather than ignore the value when it is not needed.

DateTime is the only important type that really has a problem - it is common for it to be null in the database, and if you have a row that has null value for the date column, and try to instantiate it using VisualStudio-generated database interop class, you will get a runtime exception saying that DateTime field cannot be assigned a null value.


In SQL:

CREATE TABLE [dbo].[DateTimeTest] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TimeStamp] DATETIME NULL
);

INSERT INTO [dbo].[DateTimeTest] (TimeStamp) VALUES(NULL)

In C#:

// Watch this crash!
DateTimeTest[] x = (from dt in context.DateTimeTests select dt).ToArray();



I've done a few searches, and there are quite a few cases of people reporting the problem, but no good solutions for it - most people tend to rebuild their classes by hand when they need nullability, or fudge the database.

The solution does exist, however, and it is quite simple - in the graphical representation of database dbml, right-click on the offending field, select properties, and change Nullable field to true.

This is all it takes! After that, the date field is modeled as DateTime?, and everything works just fine.

Thursday, December 25, 2008

A year of blogging

So I've been at it for slightly more than a year. I started this blog for three reasons.

First, I wanted to learn to write. In the very beginning, I had to correct or rewrite almost every sentence before making a post. There were typos, awkward sentence construction, and every stylistic problem known to humanity. Some amount of it is still there - after all, English is not my native language - but I think I am a lot better now than I used to be.

Second, I needed to have a place where I could jot things down for future reference. Some of them were simple facts that I would needed to recall periodically. Some were convenient shortcuts in coding. Some where points of view that it was convenient to have written down, for future reference.

Third, I wanted to write down a few lessons that I've learned in my career in computer industry. I was lucky to have been part of a whole bunch of interesting projects, the rise and the fall of the dot com boom, the emergence of broadband, the mobile phone revolution. It felt like a bad thing to have it go to waste: fools learn from their own experience, smart people learn from that of others. Hopefully, smart people everywhere will learn from my experiences. We need more smart people!

Attracting a lot of readers was never a goal. Yet over one hundred thousands people visited it since January 2008. Many left insightful comments from which I learned a lot. Quite a few served as a motivation for further blog entries.

The most controversial was the blog entry where I duscuss the reasons I went back to Microsoft after a year at Google (http://1-800-magic.blogspot.com/2008/06/back-to-microsoft.html). Alone, it accounted for 85000 page views out of 150000 site total. It elicited 180 comments on this site, spawned a small copycat industry of cross-posters, and was ultimately misquoted from ZDNet to NY Times.

The most visited technical article is the one on STL vector performance (http://1-800-magic.blogspot.com/2008/02/stl-vector-performance.html). It was viewed 6500 times, and is currently #1 entry on Google searches on "C++ vector performance", "STL vector performance", and just "vector performance" at Google.


A far less interesting article (http://1-800-magic.blogspot.com/2008/02/down-with-atoi.html) where I gripe about poor design of atoi API was read 3000 times, despite the fact that it is buried on the second page of Google search results on atoi.

The two articles on memory management that I consider my best technical entries - "Guerilla guide to native memory management" (http://1-800-magic.blogspot.com/2007/11/guerilla-guide-to-native-memory.html) and "Memory is not free (more on Vista performance) (http://1-800-magic.blogspot.com/2007/12/memory-is-not-free-more-on-vista.html) - have been read only ~1000 times each, despite prominent position on Google search.


I also used the blog to share a few bits of code I was toying with. About a year ago I got my hands on Sony Reader, and made a web proxy for Project Gutenberg that adds SONY LRF format to the list of available download options (http://1-800-magic.blogspot.com/2008/01/gutenberg-for-sony-pre-alpha.html). This post solicited the largest percentage of positive feedback :-). The site is still up, it has served hundreds of people who downloaded thousands of books through it.


Finally, the least popular post? This one: http://1-800-magic.blogspot.com/2007/12/us-electoral-politics.html. It's only been read 6 times :-)...

Non Piu Andrai

Wednesday, December 24, 2008

Why we should not let iPhone win...

Two articles that I spotted recently about iPhone apps, one rejected by Apple (http://www.theregister.co.uk/2008/12/23/iboobs/), another (actually, a bunch of others) accepted (http://venturebeat.com/2008/12/23/iphone-fart-app-pulls-in-nearly-10000-a-day/).

While one might observe that the classiness of the Apple crowd appears to be long gone, the important thing is not that.

The ONLY way for a developer to release an app for iPhone is through the Apple store (contrast it to any other smartphone where any piece of software can be installed from any location, be it a PC, or the Internet, and anybody can build and release applications).

And for Apple to distribute an application, someone at Apple must bless the morality of its contents. In this specific instance, Apple decided that farting is OK, while boobs (even the covered ones) are not.

And this is why we cannot let Apple win in this game. Because if we do, we will be putting one company as a judge of what is appropriate, and what is not. And I don't think there's an entity in the world which is qualified to do this.

GM is us....

"To top it off, we’ve fallen into a trend of diverting and rewarding the best of our collective I.Q. to people doing financial engineering rather than real engineering. These rocket scientists and engineers were designing complex financial instruments to make money out of money — rather than designing cars, phones, computers, teaching tools, Internet programs and medical equipment that could improve the lives and productivity of millions.

For all these reasons, our present crisis is not just a financial meltdown crying out for a cash injection. We are in much deeper trouble. In fact, we as a country have become General Motors — as a result of our national drift. Look in the mirror: G.M. is us."

http://www.nytimes.com/2008/12/24/opinion/24friedman.html?_r=1&ref=opinion

Incidentally, a whole lot of smart engineers that we have still left in computer science works on stuff that is very much akin to the financial engineering Friendman is writing about - chasing eyeballs, not users, producing Facebook apps that help people waste time rather than being productive...

Sunday, December 21, 2008

The one Google thing I miss the most

This week turns out to be exactly six months since I left Google to return to Microsoft. The year at Google was fun, and I learned a lot of new stuff. I am glad that I took this detour from my Microsoft career - it gave me a lot of new perspectives.

Six months later, what aspects of "The Google Way (TM)" do I miss the most?

Surprisingly, the free food is not it - not even close: luckily, most software engineers are paid enough so that the food costs are not really visible in our budgets.

Google's focus on engineering, where a developer owns everything about the product, including testing and the feature set, is nice at first, until you realize that it comes at a heavy price.

The products that can be built within this model tend to be smallish and not very well integrated. Every project that I've done at Microsoft was bigger in scope, more interesting as an engineering challenge, and all but two made far more money than anything I created at Google. And I am glad to be working on something really big again.

I miss the peer review system. But it is easy to replicate, and Microsoft already gives me all the necessary tools, and we are going to be trying it in my team, although I will implement it slightly differently.

At Google one needs to get positive feedback from people who are one's senior in order to be promoted. Feedback from peers and junior people does not matter very much. The problem is that at some point there are just not enough senior people around you - there are only a handful of technical fellows at Google, and less than 10 distinguished engineers, if I remember correctly.

As a result I have seen mediocre engineers grow very quickly just because they happened to work on a project that had a DE, and much better engineers stuck at lower levels because they were not so lucky.

So in my team we're going to value peer feedback much more uniformly, and assign a bigger weight to the manager feedback than the 10-15% that is customary at Google.

I don't miss my Google managers at all. They were nice people, but they didn't have much impact on my life. After a year at Google, I still do not quite understand what the role of a manager there is. Whatever they do, they certainly do not have the tools to succeed, and their impact on teams seems to start and end with allocating resources.

I worked with a bunch of very smart, talented, and passionate developers at Google. I even had the privilege of meeting Craig Silverstein through my work on the readability team and exchanging a couple of change lists with him. The amount of energy and brain power collected there is staggering.

But I also worked with a few people who were the weakest developers I'd seen in my entire career. They would show up at work around noon, eat the free lunch, browse the web, attend a few meetings, and generally be gone by 6-ish. In the 4 months I worked with them, they had each written a couple of hundred lines of code, and copied and pasted a few hundred lines more. I don't miss that project at all.

I don't miss Linux very much either - especially the C/C++ development tools. I now understand why so many smart people that I met at Google said that they are never going back to C++ after Java. I do not miss debugging with printfs.

The fact that Google had either reimplemented or wrapped every OS API - from thread and process creation to HTTP protocol handlers and RPC - did not help me appreciate the beauty of this extremely lean operating system :-). Yes, the OS was small, fast, (insert your own epithet describing efficiency here)...

But the applications that compensated for this leanness ended up being massive lumbering beasts, requiring hundreds of megabytes of RAM and a minute or more to start. And it was not because these apps were written by idiots - no, the people who created them were actually quite good. It was because they had to do a lot of things that the "bloated" Windows OS does for you.

I miss Python somewhat. It is a nice, effective script language that I learned to love. Python is a corenerstone in Google's infrastructure - everything, from the check-in tool to makefiles, is written in Python. The best thing about Python is its consistency - you can clearly see that the language had one designer, who actually DESIGNED it, rather than just stuffing random unrelated features in a la C++ (or Perl).

I think Linux people should just adopt Python as "the one script engine," and dispense with the proliferation of *sh interpreters with their horrible, horrible scripting support that leaves no doubt that it was simply bandaged on top of something that was never designed to do scripting. And after 25 years, the bandage is wearing off and the puss is seeping all around it.

But on the other hand, there is nothing - at least on Windows - that is doable with Python and cannot be done with C# in an equivalent amount of time, or faster. So while I like the language a lot, I found myself mostly using C# anyway because of it's "built-in" status on Windows and really nice Visual Studio support.

There is one thing at Google that I miss a lot, without any qualifications, with no "if"s or "but"s. It's Mondrian, the Google code review system.

It was written by Guido van Rossum, the creator of Python. It was his starter project, and it demonstrates another admirable thing that Google does, which is investing very heavily in development productivity. I would say that by creating Mondrian, Guido single-handedly improved the quality of Google code by at least 20%.

Guido describes it here: http://video.google.com/videoplay?docid=-8502904076440714866 in great detail.

To summarize this presentation in just a few sentences: you create a change list in perforce. It automatically shows on the Mondrian web site. You go to this web and request code reviews by typing people's aliases. The mail gets sent with the link to the change list representation on this web site.

The web site shows - for every file in the change list - what it was before and what it is now, side by side. To comment, you click anywhere and start typing. The comment gets attached to the line of source on which you clicked. When you're done, submit the result, and the reviewee as well as the other reviewers are notified, and can see your comments on the same web site, right inside the files that are reviewed.

The reason Mondrian works so well is because the cost of making a comment is nearly zero - which is not true for over-the-shoulder code reviews, or trading files - where someone needs to take a note, fix the code, and then the reviewer has no easy way of verifying that the suggestion has actually been followed on. The point, click, and type UI paradigm that has been successfully driving the computer industry for so many years, has proven itself indispensable once again.

Unfortunately, Mondrian is an internal Google tool, not accessible from the outside. And even if it were, it is built on internal Google infrastructure, so it will be a cold day in hell before software organizations begin sending all of their code through Google servers. Obviously, this is not likely to happen at Microsoft :-).

So now that we've reached the end of M0 and a vast majority of my team is on their well-deserved vacations, I have a bunch of free time that I can spend on toying around. I have started playing with building my own Mondrian-like system that you can actually deploy on stock software such as IIS and SQL Server - stuff that is easily available to developers worldwide.

I have several objectives.

First, I want to learn ASP.NET and SQL. For the most part of my career, I was a very low-level developer - I know a lot about operating systems, implementation of compilers, low-level network protocols and file systems. I don't know very much about high-level abstractions - I have never written anything serious in C#, my experience building web services is confined to Google's infrastructure (and as such is not very useful outside Google), and I had never used a database until about a month ago.

Second, I want my team to have a nice code review system. We've had a few attempts at reusing tools that had already existed at Microsoft, but they all proved to be either very inconvenient, or very unstable. A good functioning code review system is a boon to developer productivity. This much I learned at Google.

Third, I think the world will benefit from a nice local, retargetable code review system that can be built on top of widely available software components. So when I am almost finished, I will be releasing it on Codeplex - Microsoft's shared code repository (http://www.codeplex.com/).

Meanwhile, you can read about my progress here. :-)

Update: It's up and running. We've used it for a month and a half, for more than 200 code reviews, 2000 files, and 3000 comments. Get it here: http://www.codeplex.com/Malevich.

Interview with a Chinese banker

"Individually, everyone needs to be compensated. But collectively, this directs the resources of the country. It distorts the talents of the country. The best and brightest minds go to lawyering, go to M.B.A.s. And that affects our country, too! Many of the brightest youngsters come to me and say, “Okay, I want to go to the U.S. and get into business school, or law school.” I say, “Why? Why not science and engineering?” They say, “Look at some of my primary-school classmates. Their IQ is half of mine, but they’re in finance and now they’re making all this money.” So you have all these clever people going into financial engineering, where they come up with all these complicated products to sell to people."

http://www.theatlantic.com/doc/print/200812/fallows-chinese-banker

Friday, December 19, 2008

Stuck in the Middle Ages

No wonder we're still debating whether evolution is real or not.

We're using the British Imperial measurement system that results in pearls like the following:

"To examine innovation in steam technology, we need a measure of how good a steam engine is. One important measure is the amount of work delivered by a given amount of fuel. This can be measured by the duty of a steam engine: the number of pounds of water that can be lifted one foot for each 94 pounds of coal consumed."

http://www.fee.org/publications/the-freeman/article.asp?aid=8370.

Let's try it again: duty of a steam engine is the number of pounds of water that can be lifted one foot for each 94 pounds of coal consumed.

Think how hard physics - no, any science! - in these units...

Thursday, December 18, 2008

Conservative moral compass, part 3

"Conservative legal experts like David Rifkin (who served in the Reagan and first Bush administrations) argue that no accounting is necessary, since the worst interrogation techniques, like waterboarding, have already been abandoned and Obama is expected to make further changes."

So if someone puts a bullet through the head of this bastard and promoses to never ever do it again - we wouldn't need to prosecute him. It would be so nice to make conservatives live by their own principles!

http://www.newsweek.com/id/176044

Operator overloading

What does the following program output?

#include <iostream>

int main(int argc, char **argv)
{
volatile char *p = "hello";
std::cout << p << '\n';
return 0;
}

Wednesday, December 17, 2008

Linus on C++

Reading this was pure joy!

http://lwn.net/Articles/249460/

"C++ leads to really really bad design choices. You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap, that may "help" you program, but causes:

- infinite amounts of pain when they don't work (and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)

- inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app."

Yes... Yes. Yes!!! Finally. Somebody said it. Linus is now my hero!

Seriously, if you use C++ to its full extent - and look at inane amount of crap they put in C++0x (http://en.wikipedia.org/wiki/C%2B%2B0x) - lambdas! concepts! alternative function syntax (yes, check THAT one out!), built-in iterators! - why not use C# or Java instead? Equally slow (*), at least they are well designed.

What used to be a very much WYSIWYG language with a very well defined purpose (speed and closeness to hardware) is now becoming a random subset of everything from JavaScript to Haskell, whether it makes sense to pack it in one place or not.

(*) STL semantics encourages runaway number of memory allocations which is very similar to C# and Java. The difference is that both Java and C# have memory systems that are designed for this purpose - the cost of object creation is very, very low - whereas in C++ it is anything but. (http://1-800-magic.blogspot.com/2007/11/guerilla-guide-to-native-memory.html)

Monday, December 8, 2008

Conserative moral compass, part 2

So suppose you shoot up a bunch of innocent civilians in Iraq. Where do you get the most sympathetic jury for your trial? Why, in Utah of course!

And they don't even hide it!

"Mark Hulkower, a lawyer for one of the defendants, said the men surrendered in Utah, a relatively conservative, pro-military area, because they hoped to find a jury pool where “people are more sympathetic to the experiences of coming under enemy fire.”"

http://www.nytimes.com/2008/12/09/washington/09blackwater.html?_r=1&hp

Sunday, December 7, 2008

Cartoon characters are finally given protection they deserve in Australia!

http://www.news.com.au/story/0,27574,24767202-2,00.html

Without rendering any opinion on "morality" of drawing naked pictures of the Simpsons kids, it appears to me that the child pornography laws are passed with the intent of protecting the children from sexual exploitation.

In the case referenced above, the judge in Australia has just extended this protection to the Simpsons family...

Clearly, he must be spending way too much time in front of an idiot box!

Saturday, December 6, 2008

Monday, December 1, 2008

It's in the genes...

http://www.latimes.com/news/opinion/commentary/la-oe-gabler30-2008nov30,0,1009632.story

Conservative moral compass

Bill Kristol of Weekly Standard urges Bush to pardon the war criminals...

"The CIA agents who waterboarded Khalid Sheikh Mohammed, and the NSA officials who listened in on phone calls from Pakistan, should not have to worry about legal bills or public defamation. In fact, Bush might want to give some of these public servants the Medal of Freedom at the same time he bestows the honor on Generals Petraeus and Odierno. They deserve it."

http://crooksandliars.com/nicole-belle/ny-times-urges-bush-not-abuse-pardons

I suppose it was too bad Hitler didn't have time to pardon his henchmen...

Friday, November 28, 2008

Kentucky, 2006

"The 2006 law organizing the state Office of Homeland Security lists its initial duty as "stressing the dependence on Almighty God as being vital to the security of the Commonwealth."

Specifically, Homeland Security is ordered to publicize God's benevolent protection in its reports, and it must post a plaque at the entrance to the state Emergency Operations Center with an 88-word statement that begins, "The safety and security of the Commonwealth cannot be achieved apart from reliance upon Almighty God.""

http://www.kentucky.com/210/story/608229.html

This is 2006. No kidding. Welcome to Jesusland!

It's Thanksgiving, not a Halloween! Why am I scared?

"In fact, in commercial and academic turkey-breeding programs, adult male turkeys, called toms, can reach 50 pounds at the tender age of five months, said John Anderson, a longtime turkey breeder at Ohio State University.

"We get 50 pounders at 20 weeks, but that's at the top edge of our normal distribution," Anderson said. "We've got some adult male-line birds that went over 80 pounds.""

http://blog.wired.com/wiredscience/2008/11/turkeytech.html

Organic Avocados

"I told my wife to stop this organic food malarkey,'' said Jeremy, a beleaguered hedge-fund manager, another man who fell for an extremely beautiful yet extravagant woman.

"She went ballistic. Organic Hass avocados cost £1.75 each and she wanted me to buy six of them! In the end, I just peeled off the labels that said they were certified organic and put them on ordinary avocados – she didn't notice the difference. I did the same with bananas…"

http://www.telegraph.co.uk/finance/financetopics/recession/3527803/Recession-When-the-money-goes-so-does-the-toxic-wife.html

Tuesday, November 25, 2008

US automakers vs. Honda

"You need to give people the freedom to spend and the freedom to make mistakes," says Takeo Fukui, Honda's 61-year-old president. "If management oversight is too strong, then it's difficult to innovate."

"There's not a company on earth that better understands the culture of engineering."

Very interesting article in Forbes about engineering-dominated Honda vs. marketing-dominated automakers in the US.

This is generally true beyond car manufacturing - at most US companies marketing and finance rules, technology and manufacturing get outsourced.

Even in hi-tech, there are fewer and fewer engineers at on near the top - the trend started during the .COM boom when the geekish software companies got "integrated" into society as a legitimate make money fast industry, and it never really ended.

How many VPs did you see that are "proud of the smart people who are making all these great products", but are decidedly (and pointedly) not one of them?

We're now reaping the "rewards" of the culture where it's not smart to be smart...

http://www.forbes.com/forbes/2006/0904/112.html

Monday, November 24, 2008

You know why the economy tanked? It's because we're not religulous enough!

Under Faux News aegis, Wall Street Journal opinion page is reaching the whole new level of ridiculous...

http://online.wsj.com/article/SB122714101083742715.html

Friday, November 21, 2008

Wednesday, November 19, 2008

RIP PC Magazine

http://www.paidcontent.org/entry/419-ziff-davis-to-close-print-pcmag-focus-on-online-still-looking-for-optio/

The last time I held it in my hands was some time in the late nineties, but it is an end of an era...

Alienation

"According to presidential historian Davis Logsdon of the University of Minnesota, some Americans might find it "alienating" to have a president who speaks English as if it were his first language."

http://www.huffingtonpost.com/andy-borowitz/obamas-use-of-complete-se_b_144642.html

Taking a private jet to beg for a bailout

http://abcnews.go.com/Blotter/WallStreet/story?id=6285739&page=1

Note also the salaries of these "leaders" in the article above.

Incidentally, none of these excesses existed before Reagan's tax cuts, and they do not exist today in Europe where taxes on super-high incomes are accordingly high.

Tuesday, November 18, 2008

Mekong Delta

In 1968 US has carried an Operation Speedy Express in the heavily populated Mekong river delta. The orders were to achieve the high body count at all costs.

That was achieved: 10899 enemy casualties were reported, with only 267 American losses.

The problem? Only 748 weapons recovered. Much of the rest were civilians.

http://www.thenation.com/doc/20081201/turse

Maybe in Ohio, but not in America!

"If it wasn't for Bush we would be out of street waving white flags
waiting for the salvation army trucks to bring us our daily meal.

I fear that with a liberal at helm, the only direction we'll be
steering for is Deep, Deadly Depression.

I am contemplating moving to Canada or somewhere in Europe. Push comes
to shove, I may even move to Mexico or Hawaii, as long as it's a
different country
and I can get away with the depression that is
inevitable if a the government liberalizes everything."

http://finance.google.com/group/google.finance.358464/browse_thread/thread/5e9d0da4985a76c3?pli=1

Check out the reaction of Canadians down in the thread: "As a Canadian, i have to say, please don't come here. we don't need people like you!"

Exchange web services 2007

A few snippets from my weekly status database that show how to interact with EWS 2007.

First, you need to generate EWS 2007 proxy. In Visual Studio it is relatively easy: Project->Add service reference, enter the address of your exchange web server, for example, https://mail.microsoft.com/EWS/Exchange.asmx (you won't be able to use this one because it is obviously secured). Hit Go, then name the namespace and hit OK.

One problem with EWS 2007 is that it unfortunately requires user credentials - cleartext (they are sent using HTTPS, so the wire security is not a problem, but the user has to enter the password/user name, or the software needs to CryptProtectData the credentials and store them. Windows auth is not available.

See here for a snippet of code that stores the password SECURELY: http://1-800-magic.blogspot.com/2008/11/encrypting-data-in-net.html. Make sure you're running under real user account (not LocalService, and definitely not NetworkSerivce), otherwise anybody will be able to decrypt the password.

Once the proxy has been generated, and put in the namespace, and the namespace has been included in the file with "using" directive, we can start coding.

First, we need to bind to the service. Binding is required for all examples below:
const string EXCHANGE_URL = @"https://mail.mydomain.com/EWS/Exchange.asmx";
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Credentials = new NetworkCredential(User, Password, Domain);
binding.Url = EXCHANGE_URL;
Looking up a subfolder of inbox:
DistinguishedFolderIdType inbox = new DistinguishedFolderIdType();
inbox.Id = DistinguishedFolderIdNameType.inbox;
BaseFolderIdType[] parentFolder = new BaseFolderIdType[1];
parentFolder[0] = inbox;

FindFolderType folderRequest = new FindFolderType();
folderRequest.FolderShape = new FolderResponseShapeType();
folderRequest.FolderShape.BaseShape = DefaultShapeNamesType.AllProperties;
folderRequest.Traversal = FolderQueryTraversalType.Shallow;
folderRequest.ParentFolderIds = parentFolder;

FindFolderResponseType folderResponse = binding.FindFolder(folderRequest);
foreach (ResponseMessageType responseMessage in folderResponse.ResponseMessages.Items)
{
FindFolderResponseMessageType findFolderResponseMessage =
responseMessage as FindFolderResponseMessageType;
if (findFolderResponseMessage.ResponseClass == ResponseClassType.Success)
{
BaseFolderType[] folders = findFolderResponseMessage.RootFolder.Folders;
foreach (BaseFolderType folder in folders)
{
if (folder.DisplayName.Equals(folderWeAreLookingFor))
{
...do stuff
}
}
}
}
Here's how to get all email (we're only getting the ids of messages, the contents needs to be queried using a different request, covered later:

DistinguishedFolderIdType inbox = new DistinguishedFolderIdType();
inbox.Id = DistinguishedFolderIdNameType.inbox;
BaseFolderIdType[] parentFolder = new BaseFolderIdType[1];
parentFolder[0] = inbox;

FindItemType listRequest = new FindItemType();
listRequest.ItemShape = new ItemResponseShapeType();
listRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
listRequest.Traversal = ItemQueryTraversalType.Shallow;
listRequest.ParentFolderIds = parentFolder;

FindItemResponseType listResponse = binding.FindItem(listRequest);

List items = new List();

foreach (ResponseMessageType responseMessage in listResponse.ResponseMessages.Items)
{
FindItemResponseMessageType findItemResponseMessage =
responseMessage as FindItemResponseMessageType;
if (findItemResponseMessage.ResponseClass == ResponseClassType.Success)
{
ArrayOfRealItemsType realItems =
findItemResponseMessage.RootFolder.Item as ArrayOfRealItemsType;
if (realItems != null && realItems.Items != null)
{
foreach (ItemType item in realItems.Items)
{
if (item is MessageType)
{
MessageType message = item as MessageType;
items.Add(message.ItemId);
}
}
}
}
}
Now, suppose we accumulated all message ids that we want to get in the items list, (we presume that items.Count() > 0). We will now get all the messages as follows:
GetItemType getRequest = new GetItemType();
getRequest.ItemShape = new ItemResponseShapeType();
getRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
getRequest.ItemIds = items.ToArray();

SnippetsDataContext snippets = new SnippetsDataContext(Database);

GetItemResponseType getResponse = binding.GetItem(getRequest);
foreach (ResponseMessageType responseMessage in getResponse.ResponseMessages.Items)
{
ItemInfoResponseMessageType getItemResponseMessage =
responseMessage as ItemInfoResponseMessageType;
if (getItemResponseMessage.ResponseClass == ResponseClassType.Success)
{
ArrayOfRealItemsType realItems =
getItemResponseMessage.Items as ArrayOfRealItemsType;
if (realItems != null && realItems.Items != null)
{
foreach (ItemType item in realItems.Items)
{
if (item is MessageType)
{
MessageType message = item as MessageType;
// Message now contains everything, except for attachments.
...
}
}
}
}
}
Suppose we want to move a message to a different folder. We need to find folder's id (see above for how to enumerate folders). If we do have this id, and the id of the message we're trying to move:

MoveItemType moveRequest = new MoveItemType();
moveRequest.ToFolderId = new TargetFolderIdType();
moveRequest.ToFolderId.Item = targetFolder;
moveRequest.ItemIds = new BaseItemIdType[1];
moveRequest.ItemIds[0] = messageId;
MoveItemResponseType moveResponse = binding.MoveItem(moveRequest);
Ok, enough moving stuff around. Let's send something!

ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Credentials = new NetworkCredential(User, Password, Domain);
binding.Url = EXCHANGE_URL;

DistinguishedFolderIdType folder = new DistinguishedFolderIdType();
folder.Id = DistinguishedFolderIdNameType.sentitems;

TargetFolderIdType targetFolder = new TargetFolderIdType();
targetFolder.Item = folder;

CreateItemType createItem = new CreateItemType();
createItem.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
createItem.MessageDispositionSpecified = true;
createItem.SavedItemFolderId = targetFolder;

MessageType message = new MessageType();

EmailAddressType recipient = new EmailAddressType();
recipient.EmailAddress = "email@domain.com";

message.ToRecipients = new EmailAddressType[1];
message.ToRecipients[0] = recipient;
message.Subject = "Hello, World!";
message.Sensitivity = SensitivityChoicesType.Normal;

message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.Text;
message.Body.Value = "This is my first automated email!";

createItem.Items = new NonEmptyArrayOfAllItemsType();
createItem.Items.Items = new MessageType[1];
createItem.Items.Items[0] = message;
binding.CreateItem(createItem);
Many messages can be acted upon (moved, sent, deleted) by one command - all it takes is putting multiple messages or ids in Items.Items array.

Dealing with the web service is A LOT of code - even with the help of the proxy. Comare this to the Office interop, where most of the above tasks take 10-15 lines of code. http://1-800-magic.blogspot.com/2008/11/fun-with-outlook-and-net.html

More on EWS 2007 here: http://msdn.microsoft.com/en-us/library/bb418726.aspx

Monday, November 17, 2008

However stupid our Republican VP candidate might look...

...things are far, far worse in Russia. A couple of juicy quotes...

""Medvedev will serve his term and may be re-elected for another," says Edward Lozansky, a former dissident. "It is none of the British press's business anyway. Go and teach your British wives to cook cabbage soup.""
...

"Until last week, Svetlana, a young mother of two, held decidedly middle-class ambitions. An executive at a construction company, she was hoping to save enough to send her children to school in Britain and buy a new flat in an upmarket part of Moscow. But then, without warning, she was made redundant along with about 70 colleagues. She received no severance pay and was instead forced to sign a letter saying she had voluntarily resigned.
"They said that if I didn't sign then I could look forward to burying my own children," Svetlana says. "What kind of country do we live in? I thought we were close to becoming a civilised nation, but I've been forced to realise that that is an illusion.""

http://www.telegraph.co.uk/news/worldnews/europe/russia/3469652/Russias-crumbling-economy-provides-stiffest-test-yet-for-autocratic-leader.html

Sorting in C# with delegates

A delegate can be handy to avoid having to implement an IComparer class.

Suppose you need to sort an array of dates in descending order...

DateTime[] availableDates = allMailDates.ToArray();
Array.Sort(availableDates, delegate(DateTime d1, DateTime d2) {
return Math.Sign(d2.ToBinary() - d1.ToBinary());
});

Saturday, November 15, 2008

First encounter with T-SQL

I am building a little app for my team that collects weekly status emails and publishes it on a web site. Since I've worked on far lower level stuff most of my career (I only wrote the code that actually has UI at Google), it's fun and educating.

Using ASP.NET is quite fun actually - Microsoft REALLY nailed developer experience on this one. The API is logical, concise, well structured, and a pure joy to use. I started with having no clue whatsoever, and had a fully-functioning web app running in around two hours, and this included reading a book.

This story is about T-SQL, however. There came time where I wanted a stored procedure. On my website, there is an adminitrative user who can make changes in a database, and everybody else can do unlimited reading (anybody can see everybody's status mail), but only very limited types of writing (sign up to receive someone else's status updates in email, turn email reminders for her- or himself on and off, and join and depart a project).

So while everything other type of data access was done using LINQ, it seemed convenient to handle mutations by non-admin users via stored procedures. Specifically, I needed one right off the bat: any authenticated user - know by the alias - could sign up for status email for a person whose status was to be collected.

The task seemed quite obvious:

-- =============================================
-- Author: Sergey Solyanik
-- Create date: 11/14/2008
-- Description: Adds a subscription
-- =============================================
CREATE PROCEDURE [dbo].[AddSubscriptionToPerson]
@alias nvarchar(15),
@personId int
AS
BEGIN
DECLARE @subscriberId int

SET @subscriberId = (SELECT SubscriberId
FROM Subscribers
WHERE SubscriberAlias = @alias)

IF @subscriberId = NULL -- BUGBUG: '=' does not work!
BEGIN
INSERT INTO Subscribers (SubscriberAlias) VALUES(@alias)
SET @subscriberId = @@IDENTITY
END

IF NOT EXISTS(SELECT 1
FROM SubscriptionsPeople
WHERE SubscriberId = @subscriberId AND
PersonId = @personId)
BEGIN
INSERT INTO SubscriptionsPeople (PersonId, SubscriberId)
VALUES(@personId, @subscriberId)
END
END
Right? Wrong! If @subscriberId is NULL, the following statement:

IF @subscriberId = NULL
SELECT 'IS NULL'
else
SELECT 'IS NOT NULL'
prints out 'IS NOT NULL'! The correct way of tesing for NULL is not comparing with NULL, but using IS [NOT] NULL keyword:

IF @subscriberId IS NULL
SELECT 'IS NULL'
else
SELECT 'IS NOT NULL'

So the version of code that actually works is:

-- =============================================
-- Author: Sergey Solyanik
-- Create date: 11/14/2008
-- Description: Adds a subscription
-- =============================================
CREATE PROCEDURE [dbo].[AddSubscriptionToPerson]
@alias nvarchar(15),
@personId int
AS
BEGIN
DECLARE @subscriberId int

SET @subscriberId = (SELECT SubscriberId
FROM Subscribers
WHERE SubscriberAlias = @alias)

IF @subscriberId IS NULL
BEGIN
INSERT INTO Subscribers (SubscriberAlias) VALUES(@alias)
SET @subscriberId = @@IDENTITY
END

IF NOT EXISTS(SELECT 1
FROM SubscriptionsPeople
WHERE SubscriberId = @subscriberId AND
PersonId = @personId)
BEGIN
INSERT INTO SubscriptionsPeople (PersonId, SubscriberId)
VALUES(@personId, @subscriberId)
END
END
Unfortuately, discovering this was not trivial. You see, IS [NOT] NULL is nowhere near IF in the documentation, and neither it is in the book I was reading. Also, EXISTS works if you put your SQL query that returns NULL in the IF itself, like so:

IF NOT EXISTS(SELECT SubscriberId
FROM Subscribers
WHERE SubscriberAlias = @alias)
THEN...
...but not like this:

SET @id = (SELECT SubscriberId
FROM Subscribers
WHERE SubscriberAlias = @alias)
IF EXISTS(@id)...
Well, what should we expect from a language with the syntax and semantics right out of 1950s. I haven't worked with anything like this since FORTRAN...

Friday, November 14, 2008

Redundancy

"There is little point in building a stored procedure just to run a set of T-SQL statements only once; conversely, a stored procedure is ideal for when you wish to run a set of T-SQL statements many times."

Or shall I repeat it?

"Beginning SQL Server 2008 for Developers", by Robin Dewson.

Wednesday, November 12, 2008

Michael Lewis on the Wall Street collapse

"I’d never taken an accounting course, never run a business, never even had savings of my own to manage. I stumbled into a job at Salomon Brothers in 1985 and stumbled out much richer three years later, and even though I wrote a book about the experience, the whole thing still strikes me as preposterous—which is one of the reasons the money was so easy to walk away from. I figured the situation was unsustainable. Sooner rather than later, someone was going to identify me, along with a lot of people more or less like me, as a fraud. Sooner rather than later, there would come a Great Reckoning when Wall Street would wake up and hundreds if not thousands of young people like me, who had no business making huge bets with other people’s money, would be expelled from finance."

http://www.portfolio.com/news-markets/national-news/portfolio/2008/11/11/The-End-of-Wall-Streets-Boom

If you haven't read the Liar's Poker, I strongly recommend... It's hilarious!

http://www.amazon.com/Liars-Poker-Rising-Through-Wreckage/dp/0140143459

GM in trouble?

Check out what they're paying their CEO...
http://www.reuters.com/article/businessNews/idUSN2534738420080425?feedType=RSS&feedName=businessNews

Tuesday, November 11, 2008

Encrypting data in .NET

Encrypting:
using System.Security.Cryptography;
...
string password;
string encryptedPassword = Convert.ToBase64String(
ProtectedData.Protect(Encoding.UTF8.GetBytes(password), null,
DataProtectionScope.CurrentUser));
Decrypting:
using System.Security.Cryptography;
...
string encryptedPassword;
string password = Encoding.UTF8.GetString(ProtectedData.Unprotect(
Convert.FromBase64String(encryptedPassword), null,
DataProtectionScope.CurrentUser))

Registry in .NET

Writing:
using Microsoft.Win32;
...
const string REGISTRY_KEY = "software\\yourcompany\\yourapp";
...
RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_KEY);
key.SetValue("user", args[1]);
key.Close();
Reading:
using Microsoft.Win32;
...
const string REGISTRY_KEY = "software\\yourcompany\\yourapp";
...
string user = null;
RegistryKey key = Registry.CurrentUser.OpenSubKey(REGISTRY_KEY);
if (key != null)
{
user = (string)key.GetValue("user");
key.Close();
}

Fun with LINQ: database programming tasks in under 10 lines of code

Go to Project->New Item->Data LINQ to SQL classes. After you get the design surface, click on "Server Explorer" (a tab on the right), connect to a database, and drag over tables to the white space in the middle of the screen.

Save the resulting DBML file.

Let's say the DBML file is called Snippets.dbml, and it contains the table People (note that below LINQ class generator converted it to plural "Peoples" - a bit annoying, but... whatever).

Simplest query - get everything:

SnippetsDataContext snippets = new SnippetsDataContext();
var allPeople = from person in context.Peoples
select person;
foreach(People person in allPeople)
{...}
snippets.Connection.Close();
snippets.Dispose();

A simple precondition:

SnippetsDataContext snippets = new SnippetsDataContext();
var activePeople = from person in context.Peoples
where person.IsActive
select person;
foreach(People person in activePeople)
{...}
snippets.Connection.Close();
snippets.Dispose();

A more complicated precondition:

SnippetsDataContext snippets = new SnippetsDataContext();
var activeMikes = from person in context.Peoples
where person.IsActive && person.Name.Contains("Mike")
select person;
foreach(People person in activeMikes)
{...}
snippets.Connection.Close();
snippets.Dispose();

Get only the data you need, with anonymous types:

SnippetsDataContext snippets = new SnippetsDataContext();
var peopleNamesAndIds = from person in context.Peoples
select new { person.PersonId, person.PersonName };
foreach(var p in peopleNamesAndIds)
{
Console.WriteLine(p.PersonId + ": " + p.PersonName);
}
snippets.Connection.Close();
snippets.Dispose();

Modifying data:

SnippetsDataContext snippets = new SnippetsDataContext();
var renameMikesToJohns = from person in context.Peoples
where person.Name.Contains("Mike")
select person;
foreach(People person in renameMikesToJohns)
{
person.PersonName = person.PersonName.Replace("Mike", "John");
}
context.SubmitChanges();
snippets.Connection.Close();
snippets.Dispose();

Adding a row:

SnippetsDataContext snippets = new SnippetsDataContext();
People person = new Person();
person.PersonName = "Bill Maher";
context.Peoples.InsertOnSubmit(person);

Fun with Outlook and .NET

You need to add reference to Microsoft.Office.Interop.Outlook.

Reading email in 11 lines of code:

using Microsoft.Office.Interop.Outlook;
...
Application Outlook = new Application();
NameSpace OutlookNs = Outlook.GetNamespace("MAPI");
OutlookNs.Logon(null, null, true, true);
Folder inbox =
(Folder)Outlook.Session.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
Folder destination = GetDestinationFolder();
foreach (object item in inbox.Items)
{
if (item is MailItem)
{
MailItem mail = (MailItem)item;
Console.Write(mail.SenderName + ": " + mail.Subject);
}
}
OutlookNs.Logoff();

Sending email in 12 lines of code:

using Microsoft.Office.Interop.Outlook;
...
Application Outlook = new Application();
NameSpace OutlookNs = Outlook.GetNamespace("MAPI");
OutlookNs.Logon(null, null, true, true);
MailItem mail = (MailItem)OutlookNs.Application.CreateItem(OlItemType.olMailItem);
mail.BodyFormat = OlBodyFormat.olFormatPlain;
mail.Body = "Hello, world!";
mail.Subject = "Sent from C# code snippet!";
mail.Recipients.Add("alias");
mail.Recipients.ResolveAll();
mail.Send();
OutlookNs.Logoff();

Monday, November 10, 2008

Sarah, you’re no Hillary Clinton

“I know Hillary Clinton. Hillary Clinton is a friend of mine. And Sarah, you’re no Hillary Clinton.”

The McCain adviser who leaked that Palin did not know that Africa was not a country comes out of the closet...

http://www.eisenstadtgroup.com/2008/11/10/eisenstadt-the-source-for-sarah-palin-africa-leak-and-proud-of-it/

Reading the comments is spectacularly amusing. How did this country came to having an entire political party that viscerally resents intelligence?

----------------------
Update: likely a hoax. http://www.huffingtonpost.com/2008/11/10/martin-eisenstadt-non-exi_n_142785.html.

The comments are nevertheless hilarious.

Getting back your lost files with Vista

If there is one good thing about Vista compared to XP, it's the new storage stack, which is now on par with the server operating systems such as Windows Server 2003 and 2008.

I am still due to write a post about how to write image-based backup using VSS (volume snapshot services), but just now I used it to save a file that I thought I'd lost.

I was editing code in Visual Studio, hitting Ctl-S to save it every few modifications. Suddenly, a window popped us inviting me to save Program.cs to an alternate location. I cancelled out (first mistake), closed VS (second mistake), and went to the part of the tree where the file was. It was showing in the explorer, but I could not open it.

"Vista..." - I sighed, and rebooted the computer (in reality, I don't have a proof - or even reason to believe that it was Vista that ate the file - it is more likely a bug in Visual Studio that is to blame).

When it came back, the file was not there. Damn. Another reboot, but with "chkdsk /f c:" now to check the file system. No errors, and the file still not there. Luckily, I remembered about VSS and how it is now a part of the client operating system.

What is VSS, or "Volume Snapshot Services"?

It's a service in the operating system that periodically detects which clusters on the disk are used by the file system. Then, when any of these clusters is overwritten, before writing the new data, it copies the old information in an area of the disk reserved for it, and records it.

Then, the (read-only) image of the original (at the time of the snap) disk state can be reconstructed and mounted. So if the file system got corrupted, or a file overwritten or deleted, you can get your data back.

To do it, right-click on a file (if it's still present), or a folder, or a drive, and click on "Restore Previous Version..." menu item.



A dialog box will open inviting you to select from a bunch of snapshots that the system had taken for you at various times in the past:



Select the version, and the normal explorer window will open, pointing to the mounted image of your disk as it existed on the given date.



Find your file, and voila - you can copy it to where it should be.

Saturday, November 8, 2008

The next Depression

This promises to be a crisis of epic proportions.

People are comparing it with the Great Depression, but there is one huge difference: during the Depressions US still had it manufacturing base intact. It was a financial and social crisis, but the country had robust physical infrastructure to cope with it.

This is not the case today: US infrastructure is largely gone, and we're very quickly losing our R&D base.

I've realized how far this has gone when I took a trip to Taipei in 2003. For a large part of its history, Taiwan was one big factory. Products were designed in the United States and built here. By 2003 however manufacturing has moved on to the mainland China, and R&D moved in: we visited 5-6 companies that were building routers, and they were all purely R&D shops with manufacturing outsourced to China.

Quanta Computer in Taiwan is the largest laptop company in the world. You probably have not heard about it: the laptops that it designs (in Taiwan) and makes (in China) usually sell under Dell, SONY, and HP brand names. In 2006 it produced roughly 60% of all laptops made in the world. It also makes servers: about 40% of them.

Back in 2006 the joke that went around Microsoft was this: "Dell people think that they outsourced the manufacturing to Quanta, and Quanta people think that they outsourced marketing and distribution to Dell". Very true: a lot of what's left in the US is just that - marketing and distribution. We no longer make stuff - we just buy and sell it. With the money borrowed from Chinese.

The end of 90s were a brief respite: the pyramid scheme of .com boom had temporarily returned engineering to the top. Not for long: the enrollments into computer science programs are now below 1995 levels, US high school scores in math and science rank around 20th place in the world - below most European and a few Asian countries.

The universities churn out people who are largely incompetent. When I was interviewing graduates in China, it was immediately obvious that although there was a wide distribution in intellectual capabilities, they have all studied hard and came out of school with solid knowledge of computer science and math.

When I interview college graduates here, there is the same wide variety of IQ - and almost universal lack of basic training. At school they mostly had worked in large teams where there was one nerd that did everything, and everybody else managed process and collected customer requirements.

Our social protection net is in probably worst shape it's ever been since the New Deal. The unevenness of income distribution is as high as it's ever been: an average CEO makes 400 times the income of an average worker. This is compared to 20-40 range it's been throughout much of the history: the growth took off when Reagan lowered the upper tax bracked from 70% to 28% (it has since moved back a little to 36%).

The income distribution here is more similar to the Middle Ages than to any modern developed society.

The insane compensation packages at the top are the source of our current predicament: they incent a rationally-behaving CEO to maximize the short-term profit (after which he or she simply cashes out) at the expense of the long-term risk.

Meanwhile, the number of people lacking basic health insurance is as high as it's ever been, and the percentage of people who qualify for government assistance is as low as it's been as well, with state budgets weakened to the breaking point.

So now that we're in financial crisis, we don't have either manufacturing, or R&D capacity to lean on, nor health care or protection net to carry us through the bad times. To wit: even illegal immigration from Latin America is at its lowest point in decades.

We're in deep trouble.

So what do we do? The future depends on the new Democratic administration's willingness to take the reins, and do it vigorously.

They have the power to do a lot: strong majorities in Senate and House, and the Presidency. What they do not have is time: if the country is not on the right track in two years, if there's no improvement in the situation - beyond any reasonable doubt - they will lose the mandate, and the Obama government will be powerless.

Democrats should be quick, effective, and ruthless. Any talk about bipartisanship must end now: there's simply no time to reason with the Republican wackos in Congress - the moderates of that party are now largely gone anyway, and what's left are the crazies from the slave states, both geographically and mentally.

First and foremost, the Democrats need to take control of the media. They should push through legislation that breaks down enormous conglomerates that serve primarily corporate interests, the Rupert Murdoch epmire being first and foremost focus. Something akin to trust-busting efforts of Teddy Roosevelt, only directed at Faux News.

The discourse in the country must move away from infotainment that feeds the idiots the line that they are the greatest, smartest, most hardworking idiots in the best country in the world to actual information and informed deliberation. And yes, fewer ads :-)!

In parallel, they should break the lobbying industry. Now or never! The Deomcrats are at an enormous advantage today: with the strength of the grass root, they can survive (and win) without the lobbyists, unlike the Republicans. This will help the Democrats to solidify their power, and the government to start making the decisions that are actually good for the people, not industries and foreign countries.

Nationalize the health care. The elephant in the room that is never mentioned when the rising costs are discussed is that the lion's share of the money goes to the doctors. It's not to the malpractice insurance (<10%). Not the equipment, and not the drugs: the bottom quartile of doctors in this country make more money than the top quartile of the engineers. There's no reason for this other than the current broken health insurance system, which disintermediates the costs.

Fixing the health care is one of the few instances where the interests of the corporations and the people are identical (the fact that the companies have to pay the health care costs of their workers in the US puts them at a huge disadvantage compared to their competitors in Europe). The nationalized healthcare will give the voters immediate benefit, and the reason to vote for Democrats again in two years.

Invest in the education - big time. Literally, pour money into it. The teachers should have one of the best paying jobs in the country, and right now it's one of the worst. As a result, US's Sunday school education is better than the regular one, and we keep churning out religious fanatics. Better education correlates negatively with voting Republican, so investment here should help Democrats keep on their power.

Create massive programs for public works - and research investments. Energy independence, putting a man on Mars, rebuilding the physical infrastructure of the country - all at once. Massive spending is the only thing that can arrest the spread of the financial crisis, keep it from turning into multi-decade depression. Luckily, we're so behind in terms of progress, that the opportunities abound.

Finance these public works by devaluing the dollar and raising the taxes in the upper income bracket. The dollar os way too expensive, and it does not help: the paper should not stand in the way of the progress. Especially when much of the paper is held by foreing investors anyway :-). Cheap dollar will help revitalize manufacturing and R&D here in the US.

Higher taxes will restore the right set of incentives for the executive class: instead of get-rich-quick scheme, being a CEO will be what it was before here, and what it is now anywhere else in the developed world: a respectable, highly-paid job with high responsibilities.

Protect domestic manufacturing and R&D with tariffs. It's a myth that a country can live on moving the borrowed money from one pocket to another. To survive, we need to start - for once - making something useful again. And there's no way to do it without the base. Let's have the industrial revolution again!

Finally, investigate the abuses of the previous administration. Iraq, the torture, the wiretapping, the role of lobbyists in government must not be swept under the carpet: there's a wonderful opportunity to (1) get a lot of Republicans in jail where they belong, and (2) create and reinforce in the public mind the mental equivalency between the words "Republican" and a "crook". This association could last for a generation or two - it is very much in Democrats' interests to not pass on the opportunity.

Monday, November 3, 2008

Mercer for President!

Lee L. Mercer Jr. Welcomes You!

My Campaign Theme

The United States Government must regulate government sleepers and government regulations authorized thought, ideas, acts, actions, rights, wrongs, controversies, facts, issues and circumstantial evidence through intelligence research, law research, law enforcement research and criminal law research implementing ROTC communications research innovating education national and international.

My Platform

My platform for President of the United States Of America is Criminal Law. It is developed from my Method of Education. I was ordered to create and or invent by the United States Army that is now intact regulating the United States Government protecting it through Military Intelligence Computerization Management a new Disipline I invented and the Administration of Criminal Law Laws across the board.

My Direction

The United States Government education will perfect the vindication of it’s government regulating it’s directions and resources requirement by the law only.


http://www.mercerforpresident2008.com/home.html

Sunday, November 2, 2008

Beginning SQL Server 2008 for Developers: a book review

http://www.amazon.com/Beginning-SQL-Server-2008-Developers/dp/1590599586/ref=sr_1_1?ie=UTF8&s=books&qid=1225678034&sr=8-1

Short version: this book's information density could be much improved.

Long version: I picked this up because I am building a database app (a little snippet app which the devs on my team could use for status reports), and I needed to learn about SQL Server. I never used it before, so the book looked like a match: I am both a dev, and a database novice.

On the positive side, this book does provide information. On the negative side, the information it provides could be packed in quarter of the space. It is very, very verbose. While reading it, I could not shake off a feeling that the author was trying to fill (contractually?) pre-determined number of pages.

The book is actually very basic: it shows you how to create a database, but does not go into depth on any topic it discusses: best practices, performance considerations, and SQL 2008 specifics are some times mentioned, but never covered.

It does show you how to create a database (using UI and TSQL), add a table, set up basic relationships, back the database up, and add data: the minimum one must know to start using the database, but not enough to make one a database developer.

Lacking the depth (and breadth), the author compensates by sheer verbosity. Every dialog used is presented as a screen shot (no less than 25% of the book consists of these screen shots). Every parameter of a SQL statement is given a description, usually a perfunctory one:
  • DESCRIPTION: A description of the backup (p.193)


Sometimes, it gets to ridiculous proportions. On page 191 there is a half-page template for the BACKUP DATABASE statement. In the next paragraph, the same half page of text is repeated again - with one line added to specify a file group parameter.

Here is its description of the SQL backup modes, page 188:

"The first possibility, full backup, is straightforward. Selecting the Full option ensures that the whole database will be backed up. All the tables, the data, and so on are backed up if we use this option. We also back up enough of the transaction log (transactions committed via code, but not physically applied to the relevant tables at the point of backup). This backup would be seen as any starting point for a restore from a database failure.

The second possibility is the differential backup, also known as an incremental backup. Use the Differential backup option when the circumstances are such that a full backupis either not required or not possible. This just performs a backup on data changed since the last backup. For example, we may take a full backup on the weekend and then a differential backup every night. When it comes to restoring, we would restore the weekend full backup, and then add to that the latest differential backup taken from that point. A word of warning here: if you do take a week's worth of differential backup, and you back up to magnetic tape rather than a hard drive, do keep at least enough different tapes for each differential backup. Therefore, use a complete backup when necessary and then in the interim, use a differential backup."

What this says in so many words is: full backup backs up the entire database (duh!), and differential backup backs up the data changed since the full backup. What it does not say is when is differential backup really should be used (other than "when appropriate"), how does the system guarantee the consistency of the data on backup (it does it by using VSS), etc.

How annoying all this really is depends on how the individual reader processes the information. I ended up in a mode where I was quickly scanning through the text in search of information. I lost a bit of time doing this, and I probably glossed over a thing or two that was important, and worth knowing. The book is still probably better than reading the documentation, but if I were buying it again, I would buy something else.

Sunday, October 26, 2008

Startups in the down economy and venture financing

I've recently read an article by Paul Graham about starting a company in bad economy (http://www.paulgraham.com/badeconomy.html). The gist of his position is that founders and the business idea are far more relevant to startup's success than sources of finances, and that a lot of formidable companies (Apple, Microsoft) were founded where when the economy was not exactly booming.

His position is logical of course, but it is interesting to note that a sound startup that is cash-positive on day one, or early enough, does not require venture capital. Neither Apple, not Microsoft had VCs as their shareholders when they went public, and the founders still owned vast majority of stock on IPO - something that happens very rarely today. I suspect - although I did not check - that the same is true for Sun, Oracle, Intel, SAP, and most other companies of the pre-dot-com generation.

And of course most of the crap VCs bring to market these days is companies without a revenue model (with the business based on attracting the eyeballs, not dollars), and they get sold either to the unsuspecting public, or a different company (i.e. the greater fool) before they make their first dime. No matter - one could always count that the greater fool would be found, and separated from their money.

The more entertaining read, however, was not the Graham's article itself, but the reaction it caused in the Silicon Valley "businessmen" (http://uncov.com/paul-graham-shut-your-face).

I was surprised by the level of vitriol, before realizing that the world of the 20-something founders must be crumbling: indeed, the immediate future is probably going to be tough for Intels and Microsofts of the world, but for the "eyeballs"-centered world of the Facebook apps vendors it will be nothing short of a mass extinction event.

People keep paying for the tools through the recessions, but the marketing budget - and with it, the Facebook ad revenue - gets cut first. Watch Google earnings for the next couple of quarters...

Anyway, Graham's post and the reactions to it are things of the not so distant past. The reason I remembered them was because today I read another article, this time by Thomas Friedman (http://www.nytimes.com/2008/10/26/opinion/26friedman.html), in which he argues for the government to play passive role in the banks in which it takes ownership. The question he poses is - would a government official give Larry and Sergey a loan to found Google.

As he often is on economic issues, Friedman is full of it. The whole reason we're having a crisis is because the banks that are part of the country's monetary system are also engaged in extremely risky speculative activities. Such as venture financing, derivatives trading, and so on. Specifically - because they are currently lending money to Larry and Sergey.

This was not always the case - before 1999 banks could not do any of these high risk activities, but it meant that the depositors' money - and the country's monetary system - were safe. Venture financing, complex financial instruments, insurance were handled by organization that had these functions - not banking - in their charter. All VCs could go out of business simultaneously, and nobody - outside the startup world - would have noticed.

Incidentally, this regulation framework was introduced during the Great Depression, as a reaction to activities that caused banks to fail during that era.

Gramm-Leach-Bliley Act of 1999 - heavily lobbied for by Greenspan, and written by McCain's former economic advisor - allowed banks to enter the businesses that were previously verbotten. As a side effect, it poured a lot of money into the .COM startup market, and later into the subprime mortgages, and thus precipitated the current collapse.

So of course government officials should not be deciding whether to lend money to a young startup - because a bank should never be lending money to uncollateralized ventures in the first place. This is the business of a venture financing firm, an angel investor, the founders themselves, but not a bank.

A bank should be - and for the most part of the recent history it was - an extension of Fed, and of course it is perfectly reasonable for a government official to sit on something so close to Fed and make decisions that impact the country's monetary system!

Saturday, October 25, 2008

Wassup 2008

Titanic

An ad in Micronews (Microsoft's internal newspaper) circa 1998: "Titanic for sale. Tape 1 watched once. Tape 2 never watched."

Movies to see

Since I've been mostly critical of the movies I've seen recently, I figure the counterbalance post listing the movies I like is long overdue. Otherwise I am starting to sound like a crumudgeon.

So, in no particular order...

Fantasy


Comedy


Comedy/Drama/Romance - all in one


Animation


Adventures


Horror


War


Epics


Kurosawa


Sergio Leone


Teleseries


Russian Specifics (could be hard to understand if you were not born there before Perestroika)

Religulous: A review

We watched Bill Maher's "Religulous" this Friday. The movie had a few entertaining moments but overall it was a little bit heavy on Bill's own persona. Maher is great at editorializing, but this was a two hour movie - and it felt like over half of it was about Bill himself.

I wish we could let his subjects talk more - I have a hunch that what they would have said then would be a lot funnier.

As it were, most of the interviews followed the following template:
Interviewee: <some insanely crazy stuff>
Bill Maher: "You can't seriously believe this crap..."
Interviewee: Yes I can...
Bill Maher: C'mon... You can't.

The one moment I really enjoyed was the interview with the senator from Arkansas, Mark Pryor, where he says that one doesn't have to pass an IQ test to get into the Senate. The absolutely priceless part is watching him right after he says it, and see how he slowly realizes what he'd just said, as the smile fades away from his face...


The other were a few quotes from Founders, to illustrate what they actually thought about Christianity (that the United States of America was founded as a "Christian nation" has long been the working theory of the right wing, and a platform of Texas Republican Party).

Here are the quotes:

Lighthouses are more useful than churches.
-- Benjamin Franklin


Christianity is the most perverted system
that ever shone on man.
-- Thomas Jefferson


This would be the best of all possible worlds,
if there were no religion in it.
-- John Adams


Of course, the movie will not win any converts. The people who believe in the "talking snake" will probably never even see it. But as far as the entertainment value for the people who don't - I would say wait for the DVD.

Thursday, October 23, 2008

When the Democrats are in power, their first action should be to break up Fox News...

AMEX Centurion

http://blogs.moneycentral.msn.com/smartspending/archive/2008/10/22/all-about-the-mysterious-black-card.aspx

So apparently there are people who, while paying $2500 yearly membership fee for a credit card, do care about the reward points accrued when they rent a limo...

"Let's hope we are all wealthy and retired by the time this house of cards falters...''

Oct. 22 (Bloomberg) -- Employees at Moody's Investors Service and Standard & Poor's privately questioned the value of some mortgage-backed securities that were given creditworthy ratings, saying they created a ``monster,'' according to e-mails released by a U.S. House panel.

http://www.bloomberg.com/apps/news?pid=20601087&sid=a2EMlP5s7iM0&refer=worldwide