Sunday, May 31, 2009

Israel threatens the US

"We want to reach an agreement with the United States on ways to advance the peace process," said a senior Jerusalem official. The U.S. stance, he said, "will stall the process and bring about tension and stagnation, which will hurt both Israel and the United States."

(Emphasis mine.)

Saturday, May 30, 2009

Free web development tools for Microsoft platform

This article is about building websites using ASP.NET. "ASP.NET???" - you would exclaim in disbelief - "But this is 2009! Ruby! Rails! Python and PHP! Why would anyone even look at this boring last-century technology for building HR applications???"

There are several reasons why ASP.NET is worth more than a shrug in today's web development.

First, the tools are REALLY nice. Visual Studio absolutely rocks as a development environment.

Because of the Intellisense magic, most lines of code take only a few keystrokes to enter. Here is an example:

(1) 'c':

(2) '.':

(3) '.':

(4) '.(DownArrow':

(5) ');'

...and a line of code has been entered in roughly 8 keystrokes and under 5 seconds. When you type say a thousand lines of code per day, believe it or not, this makes a huge difference.

The debugger is fantastic - you can set breakpoint on the client and on the server, in C# and in JavaScript, and it works the way you'd expect it to work. In my days in Gmail the debugging experience was Firebug and even that involved an inordinate amount of prayer to my atheistic gods. Debugging in IE required making a pact with the devil. And as you know, Python has no debugger at all, because Pythonic code does not require debugging by definition :-).

Second, there is a lot to be said for a type-safe language.

In the world where most development is confined to 500-lines-of-Javascript-and-a-lot-of-JPEGs Facebook apps, the idea that every object is a hash map, and every squence of keystrokes is a variable makes perfect sense. Why spend time thinking about class hierarchies when we could be delighting the customers instead?

But suppose your app is 100000 lines of code. Standard software development principles - code isolation, compiler-time type checking, interfaces - become incredibly important.

How many huge applications have you seen that are written in dynamic language? I've worked on one - Gmail - which was around 250Kloc of JavaScript at the time. The only way doing anything there was possible was because of Google's internal JavaScript tools that did a lot of static code-checking at compile time, and because the v2 code base was built on object-oriented concepts - class libraries, inheritance, etc. It was very unusual - and very restricted - JavaScript for sure!

But even with all of these great tools, the life was very hard - I don't think Gmail team will be able to increase their code base very much further...

One huge advantage of ASP.NET is its ability to model an HTML page in C# - every HTML element is created as a .NET object on the server, and is then rendered into HTML. This allows your compiler to be very upfront about things that you would otherwise be finding through testing or user feedback!

For example, this is a code snippet that creates a very simple web page:

Label l = new Label();
l.Text = "<h1>Welcome!</h1>";
TextBox t = new TextBox();
t.ID = "textbox";
Button b = new Button();
b.Text = "Submit";
b.ID = "submit";
b.Click += new EventHandler(clickProcessor);

I think it was primarily because of the tools and the language that I was able to clone Google Mondrian in C# in less than a quarter of time it took Guido to write it in Python. (

Alright, alright, you would say, but don't I have to pay Micro$oft thousands of dollars for the privilege? Ruby, PHP, Python, and MySQL are free, and have you checked the going rate for SQL Server recently?

This used to be true, and it was my constant mantra at Microsoft that we should ship at least the basic dev tools for free. It was always my opinion that if we did ship free C compiler with DOS and Windows, GNU tool chain - and, consequently, Linux - would not have existed.

Maybe I was not alone in thinking this, and better late than never, so starting around 2005 Microsoft began shipping free Express version of Visual Studio Suite, as well as SQL Server Express Edition. This articles is an introduction to these tools.

Without much ado, let's dig into free development with Microsoft tools.

First, you need a free OS. Windows 7 RC is free (for a year :-)) and is available here:

On a modern DSL connection it takes about an hour to download, and another 30 minutes to install (including the updates) - at least on a virtual machine I used.

After the OS is installed, go here: and download Microsoft Web Platform using "Installer 2.0 Beta". Make sure you choose everything under the Database tab, and "Visual Web Developer 2008 Express with SP1" under Tools.

Before the installation, it will ask you what authentication scheme to use for SQL Server. Select Windows Authentication.

During the installation, it will complain multiple times about "Known compatibility issues" between Win7 and various SQL Server components. Click "Continue" every time - but you will need to install SQL Server SP1 (later).

Once the installation is complete, go to Windows Updates, and click "Get updates for other Microsoft products". Install all default and optional updates (that are not language packs). Pay attention to the optional updates - the list should include SQL Server SP1. Make sure this gets in.

Your setup is now complete! From start to finish, on a decent DSL connection, it should take no more than 2.5 hours do download and install everything.

You can use free version of Visual Studio for building web applications, and a free version of SQL Server as a backend for them.

As an example of using these tools, we'll build a simple guest book app.

Our app will consists of a database that will store comment records in our guest book, and a web front-end that would allow visitors to enter comments (as well as their names and email addresses).

Let's create the database!

Our database will be really simple. It will contain records which will consists of the record key (an integer), a 50-character name, a 50-character email alias, and an unlimited comment string.

Run Microsoft SQL Server Management Studio (from Programs->Microsoft SQL Server 2008). Right-click on the list of the databases, and select "New Database...". Enter the name of the database (GuestBook), and click OK.

This creates an empty database. Now expand its tree in the left pane, and click on the table. Select "New table...". A windows that allows you to edit the database structure will open. DO NOT save the table until all the editing is done!

First, let's create an identity field - the name would be "Id", the type "int". Right-click on the field and chose "Set Primary Key".

Then, in the list of options below, make this an identity record (a unique key that identifies the record in the database).

Then create the other fields: Author and Email (both nvarchar(50)), and Comment ((nvarchar(MAX)) - all three of them NOT NULL.

Save the table (Control-S) and name it CommentRecord:

Now that we have the place to store data, we should create a security model for it. SQL Server has two security primitives that are of interest here - database users, and SQL Server logins. "A login" is a SQL equivalent of a Windows user. When you allow a user to connect to the database engine, you create a login for this user. In our case, we want to allow IIS user to connect to SQL database, so we create a login for "IIS APPPOOL\DefaultAppPool" by right-clicking on Security/Logins and selecting New... from the menu:

Logins are global to the database engines, and are a way to identify external users to SQL. The databases also have a concept of users, which are projections of logins on the individual databases (why SQL developers decided to have two entities instead of one, beats me). So we now have to create a user for the GuestBook database, and associate it with the login we just created. We will name the user "GuestBookUser". Expand the GuestBook database tree, Security, and right click on Users, and select New. Enter the logon name (IIS APPPOOL\DefaultAppPool), the user name (GuestBookUser), and check db_datareader role membership below, as follows:

Note that we have not granted the database user any "write" rights yet, but we expect it to be able to add the records. We will do it by creating a stored procedure (a piece of code inside our database) that would add records, and grant the GuestBookUser the right to execute this code. This way, any visitor to the web site would be able to add data, but not change anything that is already in the database.

Under the database tree, expand Programmability, and right click on New Stored Procedure. The nice thing about SQL Server 2008 is that its Management Studio supports Intellisense:

Enter the following stored procedure into the query window, and click on Execute:

Now the only thing left is to grant GuestBookUser the execute access to this stored procedure. Expand Stored Procedures under Programmability, right-click on its name (refresh - F5 - if it's not there), then select Properties, and then Permissions:

We're done! Once you do it once or twice, creating simple databases like this only takes 5 to 10 minutes.

We can now create the front-end application.

Execute Visual Web Developer 2008 Express Edition AS ADMINISTRATOR. You will need this privilege level to publish the web site.

From the File menu select New Website. Pick ASP.NET Web Site template, set the language to Visual C#, and put it in a directory called GuestBook:

We will be using LINQ to access the database from our code. LINQ To SQL makes a database accessible by generating a C# object model for it. It's actually extremely nice. You can get at the database data by executing SQL-like queries directly from C#, by writing something like this:

var query = from cc in context.CommentRecords select cc;
foreach (CommentRecord r in query)
Console.WriteLine("Name: {0} Email: {1} Comment: {2}",
r.Author, r.Email, r.Comment);

LINQ supports much more complicated queries, of course, with conditions and even joins.

To add the database model, right-click on the website name in Solution Explorer, and click on Add new item. Pick LINQ To SQL Classes, and change the name to GuestBook.dbml:

We now need to connect to our database. Click the Database Explorer, then Add Connection:

Pick Microsoft SQL Server:

Set the SQL Server instance as YOURMACHINENAME\SQLEXPRESS, and select GuestBook from the list of databases. Click on Test Connection to make sure everything works:

You can now see the database in the database explorer. Expand the nodes for tables and stored procedures, and drag the CommentRecord table and AddComment SP over to their places on the designer surface:

Save everything (Control-S). The database classes are ready for use!

We need an element on the form to use as a root for our HTML object model. Every HTML element we create will attach to this element. Open Default.aspx file, and convert the empty div element inside the form to asp:PlaceHolder. It needs to have properties runat="server" and id="ActivePage". Save!

Open the Default.aspx.cs file now. This is the code we're going to write - the whole thing is barely over 100 lines long, and almost 20 of that is generated as part of the template:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
// This renders the page. Page_Load gets called both when
// the page is first displayed, and also on post-backs.
// The postback cycle initializes the page object model by running
// the code below, then sets the state of the objects from user
// input, then the handlers for the controls are called (in our case,
// it is the Click handler for the button). The handlers may (and often
// do redirect page to cause re-rendering with the new information.
protected void Page_Load(object sender, EventArgs e)
Label l = new Label();
l.Text = "<h1>Welcome to my Guest Book!</h1>";

// Open the connection to the database.
GuestBookDataContext context = new GuestBookDataContext(

Table t = new Table();

// First, display all existing comments
var commentsQuery = from cc in context.CommentRecords select cc;
foreach (CommentRecord record in commentsQuery)
TableRow row = new TableRow();
TableCell cell = new TableCell();
cell.Text = Server.HtmlEncode(record.Author) + " says...";
cell.Style.Add(HtmlTextWriterStyle.FontStyle, "italic");
cell.Style.Add(HtmlTextWriterStyle.Color, "blue");
cell.ColumnSpan = 2;

row = new TableRow();
cell = new TableCell();
cell.Text = Server.HtmlEncode(record.Comment);
cell.ColumnSpan = 2;


// Now create the form for a user to enter comments.
TableRow author = new TableRow();
TableCell name = new TableCell();

Label authorNameLabel = new Label();
authorNameLabel.Text = "Your name:";

TextBox authorNameInput = new TextBox();
authorNameInput.ID = "name";
authorNameInput.MaxLength = 50;

TableCell email = new TableCell();

Label authorEmailLabel = new Label();
authorEmailLabel.Text = "Email (will not show):";

TextBox authorEmailInput = new TextBox();
authorEmailInput.ID = "email";
authorEmailInput.MaxLength = 50;

TableRow comment = new TableRow();

TableCell commentCell = new TableCell();
commentCell.ColumnSpan = 2;

TextBox commentInput = new TextBox();
commentInput.Columns = 80;
commentInput.Rows = 20;
commentInput.TextMode = TextBoxMode.MultiLine;
commentInput.ID = "comment";

TableRow submit = new TableRow();

TableCell submitCell = new TableCell();
submitCell.ColumnSpan = 2;

Button submitButton = new Button();
submitButton.Click += new EventHandler(submitButton_click);
submitButton.Text = "Submit comment.";

if (Page.IsPostBack)
TableRow error = new TableRow();

TableCell errorCell = new TableCell();
errorCell.ColumnSpan = 2;
errorCell.ID = "error";

// This is run when the user clicks on the Submit button
void submitButton_click(object source, EventArgs e)
string comment = ((TextBox)FindControl("comment")).Text;
string name = ((TextBox)FindControl("name")).Text;
string email = ((TextBox)FindControl("email")).Text;
if (String.IsNullOrEmpty(comment) || String.IsNullOrEmpty(name) ||
TableCell error = (TableCell)FindControl("error");
Label l = new Label();
l.Text = "You need all three values!";
l.Style.Add(HtmlTextWriterStyle.Color, "red");

GuestBookDataContext context = new GuestBookDataContext(

context.AddComment(name, email, comment);


// This causes the page to be redrawn with the new comment in it.

When the code is done, you can run it directly from Visual Studio (F5), and all normal debugging primitives (breakpoints, stepping, etc) work as you'd expect them to work.

Let's deploy the web site to the real web server now. Create a directory under c:\inetpub called GuestBook. Right-click on the web site name in the Solution Explorer, and pick Copy Website option. In the dialog that opens, click on the connect button, select File System, and navigate to c:\inetpub\GuestBook. Select all the files on the left and click on the right arrow to copy them to the target directory:

Open IIS manager, navigate to Default Website, right-click on it, and pick Add Application. In the dialog box that opens enter GuestBook as the name, and c:\inetpub\GuestBook as a path to the application.

Now go to the Firewall Control Panel Applet, and open the port for IIS:

This is it!

Google I/O 2009

An interesting, if long, video:

Main theme is HTML 5. The consequences of it for Silverlight merit quite a bit of thought. Silverlight comes with far better tools, of course - the dev experience will be very hard to compete against. But HTML 5 will have the advantage of ubiquity.

The other very interesting demo - for me, at least - was Java support in Google App Engine. It's an Eclipse plug-in with a built-in deployment support, GWT ( and server-side support all built-in. Not nearly as slick as ASP.NET, but definitely a step in that direction.

A minor thing that I found quite funny, actually, was that the main presenter on the conference was Vic Gundotra - a former marketing/evangelist guy from MSFT who is now a VP of Engineering at Google. The silliness of Google management strikes again - say what you want about Microsoft, but at least our engineering managers are real engineers :-).

Wednesday, May 27, 2009

In Korean news...

Absolutely hilarious piece...

Incidentally, I cannot help noticing that "Korean Central News Agency" has a Japanese domain suffix... This is what Wikipedia has to say about Internet in North Korea:

"North Korea's first Internet café opened in 2002 as a joint venture with South Korean internet company Hoonnet. It is connected via a line to China. Foreign visitors can link their computers to the Internet through international phone lines available in a few hotels in Pyongyang. In 2005 a new internet café opened in Pyongyang, connected not through China, but through the North Korean satellite link. Content is most likely filtered by North Korean government agencies.[3][4] In 2003 a joint venture called KCC Europe between businessman Jan Holterman in Berlin and the North Korean government brought the commercial Internet to North Korea. The connection is established through a satellite link from North Korea to servers located in Germany. This link ended the need to dial ISPs in China.[5]

KCC Europe is attempting to regulate the .kp country code top-level domain (ccTLD); as of 2008[update] its site ( and Naenara ( are the only known to be active in the .kp domain. Its IP address resolves not to Asia but to servers at Internet Provider Berlin ( in the German capital."

Tuesday, May 26, 2009

No sex for iPhone users (via Reddit)

"Apple has rejected Eucalyptus, an ebook reader that facilitates downloading public domain books from Project Gutenberg, because some Victorian books mention sex."

Monday, May 25, 2009

Priceless! (from Reddit today)

Filed under Dear Jimmy...

And the first comment:
"Dear Jamail, I hope all is well in Guantanamo, though we all know better. We're very proud that you've not lied while being tortured. It could be a disaster if you give them a reason to attack more innocent people in order to make the suffering stop.

Dad was arrested because our neighbor covets our farmland, even though it hasn't seen water in 6 months. Your little brother decided to join the Baghdad police, but became a militant when he discovered that he could make more money from bribes from the soldiers. He lost his leg when an IED went off. Your sister was raped by mercenaries and then killed to cover it up. I tried to appeal to the government, but apparently they're not subject to our laws. There's still so much death. It's hard to stay hopeful.

There's an American soldier next to me reading a note complaining about seatbelts. I wonder if they even know why they're here."

Sunday, May 24, 2009

Why you should always buy memory separately

Dell, Latitude E6500, (through large enterprise portal, today): 4GB is $135

Newegg: 4GB is <$50

US health care by the numbers

Giving back capital

Constantly in the news here is the push from the banks to return government investments - the TARP funds - to escape from the strings that were attached to that money - specifically, the limits on executive compensation.

This is being discussed as if it were the most natural thing in the world - of course bankers want to be paid more! The question of how returning cheap capital benefits the shareholders (obviously, it does not) - ostensibly, the owners of these enterpirses - is never even mentioned.

It's a really weird concept of capitalism that we have here!

Wednesday, May 20, 2009

Breaking change in Malevich

This will read as a daily WTF, unfortunately... but after 6 months of development, I found a really, really nasty bug in Malevich, and if you're maintaining an installation, you should read this.

Interestingly, the bug was in my face all this time, I just wasn't paying attention.

Malevich stores a bunch of timestamps in its database - one for change list itself, one for each review iteration, and one for each file version. Normally these are stored in UTC - after all, how else would you store times in a web application where users are scattered around the globe?

Well, as it turned out, all but not all. Change list time stamp was stored as local time. Of course the bug was on display on the dashboard all this time, literally in my face. But I think this was because all the rest of the dates were in UTC and therefore not very useful - I just taught myself to ignore all time stamps. So I never noticed that unlike all the rest, these ones looked correct - and they should not have!

Anyway, for quite a while Malevich fielded complaints that the time stamps are silly, and I was thinking on and off on how I might fix that. You see, .NET runtime which Malevich is built upon is great at manipulating the time, except for one thing - the web site has no idea what user's time zone is - this is by design, a privacy issue.

The client side does know what the local time offset is, so the only way to transform time correctly must lay with the client.

So this is what Malevich does - each time stamp is wrapped in a <span id='timestamp' name='timestamp> element. When the page loads, I get all the elements by the name 'timestamp', and convert them to local time.

The conversion is pretty crappy from the globalization perspective (heck, but this is *free* software :-)) - because default JavaScript time conversion functions are terrible - they produce very long strings (for example, days of the week are spelled out by some browsers).

So I compose the date/time string myself, in US format. The only thing where I try to be smart is determine if the format is 12- or 24-hours upfront and then generate the date that would use the same format. Which does not work on Chrome because it uses 24-hour format no matter what.

// Copyright (C) Sergey Solyanik for The Malevich Project.
// This file is subject to the terms and conditions of the Microsoft
// Public License (MS-PL).
// See for
// more details.

// Javascript module to recalculate times to browser local.

// Is time a 24-hour format or AM/PM?
var TIME_FORMAT_24HR = ComputeDateFormat();

// Recomputes all date times from UTC to local.
function RebuildDates()
var dates = document.getElementsByName('timestamp');
for (var i = 0; i < dates.length; ++i)
var date = new Date(dates[i].firstChild.nodeValue);

var month = date.getMonth() + 1
var year = date.getYear()
var day = date.getDate()

if (day < 10) day = '0' + day
if (month < 10) month = '0' + month
if (year < 1000) year += 1900

var hour = date.getHours();
var minute = date.getMinutes();
var seconds = date.getSeconds();

var suffix = '';
if (hour < 10) hour = '0' + hour;
if (hour < 12) suffix = ' AM'; else suffix = ' PM';
if (hour == 0) hour = 12;
if (hour > 12) hour -= 12;
if (hour < 10) hour = ' ' + hour;

if (minute < 10) minute = '0' + minute;
if (seconds < 10) seconds = '0' + seconds;

dates[i].firstChild.nodeValue =
[month, '/', day, '/', year, ' ', hour, ':', minute,
':', seconds, suffix].join('');

// Checks if the date in the current locale is AM/PM or 24 hours.
function ComputeDateFormat()
var dateString = (new Date()).toLocaleTimeString();
if (dateString.indexOf(' AM') == -1 && dateString.indexOf(' PM') == -1)
return true;
return false;

// Makes RebuildDates be called on page load.
if (window.attachEvent)
window.attachEvent('onload', RebuildDates);
if (window.onload)
var curronload = window.onload;
window.onload = function()
window.onload = RebuildDates;

Anyway, so I make this change, and now I start looking at dates very closely, and - crrrrap! - all the time stamps now look great, except the most important one - the change list time stamp!

And the worst part of course is that it's in the database! Moreover, it's data! And it's now on a few dozen servers at Microsoft alone, and I have no idea how to even find them.

Anyway, I put notices on the web site (, and on this blog (you're reading it), and in the change list description, and on Microsoft's internal share point site for Malevich.

I modify the installer so that it detects this condition (or, rather, the right version transition), and tries to fix up the problem:

USE [CodeReview]

DECLARE @UTCDate datetime
DECLARE @LocalDate datetime
DECLARE @TimeDiff int

SET @LocalDate = GETDATE()
SET @TimeDiff = DATEDIFF(hh, @LocalDate, @UTCDate)

UPDATE [dbo].[ChangeList] SET TimeStamp = DATEADD(hh, @TimeDiff, TimeStamp)

What else can I do?

Of course, the script above does not work completely, either, because it does not account for the daylight savings time (which is really, really hard to compute in T-SQL - I love human time system!), and because it assumes that local time is the same as server time, which is of course incorrect, because a bunch of teams use the tool between here and China... But it does make the time somewhat more right than it was before.

So this is the story of the worst bug in Malevich in the 6 months since it was born.

And the moral of the story... what is the moral of this story? I wrote it primarily to attract the attention of Malevich admins to the fact that they need to be thoughtful about their next upgrade. But if you have a suggestion for a witty ending, offer it in the comments section! :-)

Why do Catholic clergy not oppose gay marriage in NY?

"The state’s Roman Catholic bishops have been somewhat distracted, too, having focused their lobbying energies this session on defeating a bill that would extend the statute of limitations for victims of sexual abuse to bring civil claims, and have appeared unprepared for the battle over marriage."

Wow! Just... wow!

Tuesday, May 19, 2009

Serious play (TED)

Fair warning: allocate 30 minutes upfront. You won't be able to stop once this starts!

Going-away party

"Green was convicted last week in U.S. District Court in Kentucky of murder, rape, conspiracy and obstruction of justice in connection with a 2006 rape-and-murder south of Baghdad. A jury found him guilty of raping a 14-year-old girl, then killing her and setting her body on fire to destroy evidence. Green also was found guilty of killing the girl's parents and 6-year-old sister.
Ruth, who is John Green's sister, noted for the jury that Green's mother is not at the trial this week. The mother is moving and had to attend a going-away party, Ruth said."

Monday, May 18, 2009

Monday, May 11, 2009

Telescopes can see... photons? (via Reddit).

"Thursday, the Europeans will launch two much more advanced telescopes (right) that can see photons, even those reaching back to the Big Bang. Hubble sees visual light."

I kid you not.

This is a "technical" publication...

Where are you, Robin Crusoe? Where are you? Where have you been?

Monday, May 4, 2009

Stretched on $500k/year

"Nor does he appreciate being branded as "rich" when it's far from certain he'll ever build the kind of lavish nest egg the truly wealthy enjoy, especially after the current market meltdown."

"Kelly Lynch, the owner of a commercial maintenance company in Redondo Beach, Calif., is raising two kids with her partner, Jill Fenske, on a household income of $400,000. She's saving $800 a month for the children's college fund and $4,000 a month for retirement - a number that someday might make her rich. "If I blew my money like other people, I'd feel rich," says Lynch. Her views on taxes are befitting a born entrepreneur: "I think it would be unfair if someone tried to raise my taxes," says Lynch. "I don't think people should be penalized because they earn more.""

"Even at the upper end of the HENRY group, our cover subjects, Lindsay Mayer and her husband, Zach, a Dallas attorney, feel stretched on $500,000 a year."

"Tony Molino, 50, an attorney in Rancho Palos Verdes, Calif., speaks for legions of HENRYs: "I've worked 50 to 60 hours my entire life, and I don't have a lot left over at the end of the month. I'm comfortable, but when Joe Biden talks about sucking it up, getting patriotic, and paying more taxes, I get livid.""

Poor people, not sure if they will ever be TRULY rich.

Here's a book that shows what really means to work hard: And it is not sitting at the desk for 2 hours more a day. It's having 3 jobs as a janitor, a waitress, a maid, and despite working 14 hours a day not having enough money to rent an apartment or go to a doctor...

Sunday, May 3, 2009

To Joe the Plumbers among us...

...who vote for lower taxes for the rich because some day they expect to be rich themselves: why not buy TWO lottery tickets instead of one? The extra money from the second win will take care of the taxes!

"By international standards, the United States has an unusually low level of intergenerational mobility: our parents’ income is highly predictive of our incomes as adults. Intergenerational mobility in the United States is lower than in France, Germany, Sweden, Canada, Finland, Norway and Denmark. Among high-income countries for which comparable estimates are available, only the United Kingdom had a lower rate of mobility than the United States."

Saturday, May 2, 2009

Why economic and social liberalism trends are incompatible

US has two dominant parties - the economically liberal but socially conservative Republicans, and socially liberal and economically conservative Democrats.

Many in my circle - the professional class - were long yearning for the third alternative - a party that is liberal both economically and socially. Someone to represent me :-)!

Why is this not happening? Unfortunately, for a reason.

Unrestricted economic liberalism mostly benefits the upper classes.

The lower classes are less educated, more religious (church and especially Christianity historically being used as a way to keep people in their place), and therefore more socially conservative.

Since the upper classes do not have enough votes to advance their agenda, they need to coopt the lower classes to vote against the lower classes' economic interests.

This of course is done by throwing down whatever red meat issues are currently at hand - "family values", gay marriage, "security", "morality", "gun rights", etc. Most of it is either social conservatism or fear because this is what the masses respond to.

And this is why economically liberal parties are bound to be socially conservative. There is simply no way for them to attract enough followers to matter otherwise.

Which is why you have such a high incidents of hypocrisy among Republican leaders - from Rush Limbaugh abusing drugs while preaching death to (other) drug addicts, to Larry Craig's restroom incident. They don't really give a flying f*ck about morals (or anything else they sell - gun rights, security, etc). They are just using this to get more idiots vote for them.

What does this say about the rich? Not much, unfortunately (I cannot bring myself to call Wall Street bankers and automaker CEOs "the elites" which to me means "the best"). By trying to extract the last penny while stirring the worst instincts in the society, they retard the progress of civilization.

Yes, they are rich, but as a result time moves slower for everybody. But you know what? The quality of life and the average longevity of the middle class in the age of antibiotics turns out to be better than that of the royalty in the Middle Ages.

Trading stem cell research for a few thousand bucks in taxes is not smart, and proves once again that IQ and compensation in today's America are unfortunately not correlated.

And this is usually the beginning of the end...

Why is it socially acceptable to be a conservative?

You generally don't see many people go around and say "I am a fascist!" or "I am a racist!". And yet there are plenty of people who proudly declare themselves to be conservative.

Let's take a brief look at the history.

Spanish Inquisition's goal was to suppress heresy - or, in other words, preserve traditional religious beliefs. It was a conservative movement that resulted in executions of thousands of people.

US itself was founded by progressives - conservatives were known as Loyalists at the time.

Over the last couple hundred years conservatives, standing athwart history (in the words of William Buckley), have opposed most of the civilization advances that we now take for granted:
  • emancipation of slaves
  • women's suffrage
  • 8 hour workday
  • limitations on child labour
  • desegregation and racial equality
  • Social Security
  • Medicare

And you don't have to go too far back in time - it is probably safe to say that in 1960s most conservatives supported segregation, and that in 1920s most of them were against women's suffrage. You just cannot say the same about liberals.

Today, history is repeating itself with conservative attitudes towards everything from torture and gay rights to healthcare reform.

So why is the conservative brand still acceptable in the mainstream society after all of this? What am I missing?