Perversion and the Four Day Weekend

metropolis

For me, a four day weekend around Thanksgiving is a great opportunity to catch up on work.  On reflection, however, it makes me think that a third section could rewardingly be added to Rousseau’s Discours sur l’origine et les fondements de l’inégalité about our further fall from the mythical natural state and the gentle yokes we place upon ourselves for the sake of both society and financial independence.  Trying to find time to further steal time from my family is clearly a perversion of some sort and I don’t know why it isn’t a pretext for revoking spiritual communion in religious faiths which still take the spiritual realm with a degree of seriousness.

Perhaps it was Hegel (but perhaps it was someone else — Kierkegaard?) who wrote that the churchmen of today walk around as if God is dead.  No longer in an academic milieu, I’ve lost the habit of striving for accuracy in the archeology of knowledge.  All I know is that someone said it (or perhaps not).  The as if is important. While I was a grad student in philosophy (and before I became a grad school drop out) we often spoke about as if metaphysics, which I took to mean the things we were required to believe in order to have confidence in order and purpose in the physical world.  In truth, however, order and purpose are illusions.  The prevailing philosophy of mind of that time – and currently, as far as I can tell, outside of the brilliant work being done by David Chalmers – holds that consciousness itself is merely an illusion.  That movement in philosophy went back in a revisionist archaeology of knowledge to show that even Descartes never took his arguments for the existence and necessity of God seriously, and so – if one follows this alternative argument read between the lines of the Meditations – neither is the problem of other minds ever resolved nor the ego sum affirmed.

We robots who think we are something more, nevertheless, abide.  I’ll throw in a tentative speculation into the archaeology of knowledge here and remind the reader that robot is a Russian derivative meaning “worker”.

Somewhere in the sediments of unconsciousness that make up our neural pathways we all recognize this Archimedean fixed truth of meaninglessness – we feel it in our bones and experience it in our daily lives.  The secret to success is determined by how we pivot on this truth.

When I was occasionally allowed to teach ethics (so far had academia fallen that we no longer even attempted to teach virtue) I felt a small degree of triumph if I could at least get students to the point of defining ethical behavior as the effort to think about the moral implications of what they were doing before they did something wrong.  It meant they had found the pivot.

So how does one pivot around God – Whom we secretly and sometimes openly suspect to be deceased?  Lucretius the first century B.C. Epicurean posited that the world was made up of chance and freely bouncing atoms – is our modern zeitgeist so different? In a world without order – and consequently without rewards for the good or punishment for the wicked (take the CEOs of our financial institutions as examples if you must have one) – hard work, the cornerstone of Lutheran and Calvinist theology – seems rather pointless.  The common lament of the underachiever is that the bullshitter succeeds while the grunt goes another year without a raise or a promotion.

And so that theology must change.  The theology of election – the notion that there are a set number of souls who will go to heaven – morphed in the 19th century into a doctrine that the elect would be known by their worldly success, for they were blessed by God.  But in a world of pure chance, how does an as if theology make sense of this?

The Atlantic Monthly’s most recent issue posits that mega-churches created the recent economic collapse we are currently all living through.  The argument is that “theology of prosperity” encouraged parishioners to over-extend their credit, to buy homes and cars they couldn’t afford while banks were more than glad to help them do so, because such acts of blind faith in future prosperity constituted faith in God’s goodness.  To act foolishly, and bet one’s future on chance, is as close as we can come to true faith.

I find no immediate reason to excoriate the pastors.  In a world in which we act as if God and rational order are dead and chance rules all, this is sound advice.  Furthermore, for those whom chance blesses, it actually brings souls closer to the absolute.  The recipients of this theologically and fiscally dubious advice were typically the poor, the roboti, looking for ways to improve their stations.  Their pastors used this natural desire to bring them closer to the divine.  As a viewer of reality shows and Lifetime bio-pics as well as a proponent of lottery money as a great source of revenue for education, I have no reason to doubt that this is the future toward which we are all headed.  Why work toward success when all we have to do is wait for it.

Being a software programmer, I have very little sense of history.  I have to look at my resume to discover how long I have worked with a particular language, and I have very little idea where these languages came from.  As an industry, programming always looks to future successes and rarely back at past mistakes.

My spouse, on the other hand, has a rich history she maintains a retells, developing a beautiful tapestry of traditions she freely shares with anyone who enters our lives.  She recently gave several talks at my daughter’s elementary school about the Russian Revolution and its aftermath using her own family narrative as a way to make sense of it.  One great-grandmother was a peasant while the other was an aristocrat.  By chance – and some peculiar contrivance – they knew each other in a private girls school where the poor relative envied the wealthy one for her oranges, which were eaten every day in the gardens of the academy.  Then comes a series of confusing events tied together through rare documents and pictures.  The children of the two schoolmates marry — there are photos.  The revolution comes.  The poor great-grandmother’s husband is taken away to the gulag – evidenced by a single NKVD document signifying his eventual release after three years servitude.  Letters and a death certificate mark the passage of the relatives who join the White Army as they fight — and flee — the Red Army across the broken Russian Empire, eventually surrounded and killed.  The Germans invade the area of Ukraine where the family estates are.  The family leaves Ukraine on the promise of work in Germany, only to end up at a labor camp in Auschwitz for Osterlanders.  They escape when the Red Army liberates the camps and executes the Russians they happen to find there.  They end up at a displaced persons camp (their papers now declare them as apatrie) and eventually make their way to New York, then Washington D.C., where a grandmother works for years at the Voice of America’s Russian Bureau but does not live long enough – none of these émigrés do – to see the fall of the Berlin Wall.

Within the fabric of this narrative there are many more stories, of course, few of which can be verified but all of which are colorful.  There are even more stories lost forever because they were so traumatic no one would speak of them.

The story I want to bring to the fore is of how Baba Neela, the peasant great-grandmother, taught the émigrés the traditions of old Russia which they had either forgotten or never had a chance to learn – how to pray in an Orthodox church, how to pray at home, how to throw a party, how to make traditional meals, how to drink one’s tea, how to enjoy life with one’s family and friends.  Also the lessons embedded in these traditions –that personal rewards only come in the afterlife, while material rewards, in a world dominated by chance, are found in the success and happiness of one’s children.

The problem with long weekends is that it gives one too much time to think.  The aftermath of 9/11 was like a condensed long weekend.  Productivity across the country went down as people realized that there were things more important than work or money.  The roads on Sunday were clogged with people returning to church, realizing that it is the fixed point of consolation in an uncertain world.

We quickly overcame that moment of excited introspection, however.  We returned to more standard patterns of as if theology and as if expectations.

Despite that, my own nagging as if expectations from another time are returning over this holiday.  For the past few months I had been trying to figure out how to get my children into soccer leagues and karate classes, since that is what is expected.  But now I’m stuck on another notion which I imagine to be the traditional education of a well-raised child of the last century.  I want each of my three children to learn a language.  I want them each to learn to play a musical instrument.  And I want them each to be well-versed in poetry and classical literature. 

With languages, they will be able to travel from country to country if required by troubled times.  With music, they will always be welcome at a party.  With literature, they will know how to enjoy their lives.  The public schools, I expect, will get them up to speed on science and mathematics.  And so the XBOX has just been turned off while the TV has been silenced.  I have work to do – promised and as yet undelivered –  but I am picking up a book instead – one by Tim Powers in an attempt to reinvent the lives of Lord Byron and Percy Shelley according to his own peculiar vision of the hidden world.

Addendum to Dynamic Method Bags

Bill Wagner has an interesting article on MSDN about implementing Dynamic Objects in C# 4: http://msdn.microsoft.com/en-us/library/ee658247.aspx.  He leaves it up to the reader to figure out the right way to implement the class he describes and provides suggestions.  This is a great way to structure a propaedeutic of this sort, as it affords the clever reader an opportunity to dig into the material on her own.

At the same time, it is often helpful to have a key against which to compare one’s own work.  To that end, the full code required to run the sample application described in the article follows.

Here is the code that serves as our test.  Bill Wagner describes an object that inherits from DynamicObject that will run the following code:

    var newType = new MethodBag();
    newType.SetMethod("Write", () => Console.WriteLine("Hello World"));
    newType.SetMethod("Display", (string parm) => Console.WriteLine(parm));
    newType.SetMethod("IsValid", () => true);
    newType.SetMethod("Square", (int num) => num * num);
    newType.SetMethod("Sequence", () => from n in Enumerable.Range(1, 100)
                                        where n % 5 == 2
                                        select n * n);
    dynamic dispatcher = newType;
    dispatcher.Write();
    var result = dispatcher.IsValid();
    Console.WriteLine(result);
    dispatcher.Display("This is a message");
    var result2 = dispatcher.Square(5);
    Console.WriteLine(result2);
    var sequence = dispatcher.Sequence();
    foreach (var num in sequence)
        Console.WriteLine(num);

    Console.ReadLine();

 

Here is an implementation of MethodBag that will fulfill the expectations established above:

internal class MethodBag: DynamicObject
{
    private Dictionary<string, MethodDescription> methods = 
        new Dictionary<string, MethodDescription>();

    #region Method Descriptions

    private abstract class MethodDescription
    {
        internal abstract int NumberOfParameters
        {
            get;
        }
        internal Expression target
        {
            get;
            set;
        }
        internal abstract object Invoke(object[] parms);
    }

    private class ActionDescription: MethodDescription
    {
        internal override int NumberOfParameters
        {
            get { return 0; }
        }
        internal override object Invoke(object[] parms)
        {
            var target2 = target as Expression<Action>;
            target2.Compile().Invoke();
            return null;
        }
    }

    private class ActionDescription<T> : MethodDescription
    {
        internal override int NumberOfParameters
        {
            get { return 1; }
        }
        internal override object Invoke(object[] parms)
        {
            dynamic target2 = target;
            target2.Compile().Invoke(parms[0]);
            return null;
        }
    }

    private class FuncDescription<T> : MethodDescription
    {
        internal override int NumberOfParameters
        {
            get { return 0; }
        }
        internal override object Invoke(object[] parms)
        {
            dynamic target2 = target;
            return target2.Compile().Invoke();
        }
    }

    private class FuncDescription<T,S> : MethodDescription
    {
        internal override int NumberOfParameters
        {
            get { return 1; }
        }
        internal override object Invoke(object[] parms)
        {
            dynamic target2 = target;
            return target2.Compile().Invoke(parms[0]);

        }
    }

    #endregion

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args
        , out object result)
    {
        result = null;
        if (!methods.ContainsKey(binder.Name))
            return false;
        // Described later
        MethodDescription method = methods[binder.Name];
        if (method.NumberOfParameters != args.Length)
            return false;
        result = method.Invoke(args);
        return true;

    }

    #region Set Methods

    public void SetMethod(string name, Expression<Action> lambda)
    {
        var desc = new ActionDescription { target = lambda };
        methods.Add(name, desc);
    }

    public void SetMethod<T>(string name, Expression<Action<T>> lambda)
    {
        var desc = new ActionDescription<T> { target = lambda };
        methods.Add(name, desc);
    }

    public void SetMethod<T>(string name, Expression<Func<T>> lambda)
    {
        var desc = new FuncDescription<T> { target = lambda };
        methods.Add(name, desc);
    }
    
    public void SetMethod<T,S>(string name, Expression<Func<T,S>> lambda)
    {
        var desc = new FuncDescription<T,S> { target = lambda };
        methods.Add(name, desc);
    }

    #endregion
}

 

Your output should look like this:

Hello World

True

This is a message

25

4

49

144

289

484

729

1024

1369

1764

2209

2704

3249

3844

4489

5184

5929

6724

7569

8464

9409

Last Night’s Atlanta Silverlight Meetup

Silverlight Meetup

http://www.meetup.com/The-Atlanta-Silverlight-Meetup-Group/

http://www.silverlightatlanta.net

Following the morning release of a Silverlight 4 beta, Shawn Wildermuth switched gears and spoke for 70 minutes about the new Silverlight 4 features at last night’s Atlanta Silverlight Meetup. He was originally scheduled to speak on Line of Business applications, but based on a show-of-hands decided to give this much more timely presentation.

The cellar of 5 Seasons Brewery was packed for the event and there was standing room only in the back. Because of the NDA, it appears that the Atlanta Silverlight Meetup got to see the first full presentation on Silverlight 4 outside of Redmond and Los Angeles, thanks to Shawn.

 

New Edition of Effective C# in Progress

effective_csharp

I just noticed that Safari Books has put up a rough cut of the 2nd Edition of Bill Wagner’s Effective C#.  My Safari license only allows me to preview but I can already see from the table of contents that he is including new chapters on working with C# 4.  This is pretty exciting.  If you recall, the 1st Edition only covered C# 1 and after a largish gap Bill Wagner published a completely different book, More Effective C#, to cover the C# 2 and C# 3 features.

I have long recommended both of Bill’s books to anyone who wants to get a deeper understanding of the C# language.  I’ve only recently started seriously reading through John Skeet’s C# In Depth, however.  I was originally put off with how much time he puts into explaining C# 1 and C# 2.  Now that I am into the second half of the book, I am very excited about his coverage of lambdas in C# 3.  His passion about this interesting language feature is both palpable and infectious.  He also does a good job of clearing up the fud around the stack and the heap.

Having these three books on the bookshelf will make anyone a more effective C# developer – well, that’s an idiom of course.  To be clear, having these three books and also reading them will in fact make anyone a more effective C# developer.  Well – just to be extremely clear – I should have said “reading and re-reading them”.  I’ve read through both of Bill Wagner’s books twice and actually had to read his introduction to generics about 6 times before I finally understood most of what he is saying.  The fault however is due not with the exposition and only partly due to the limited faculties of this non-ideal reader – C# programming can be extremely complicated stuff and we are all fortunate to have both Bill Wagner and John Skeet doing the heavy lifting involved in explaining it to the rest of us.

Is there a doctor on the plane?

tdc 003

I have just returned from a private conference in northwest Arkansas hosted by Tyson Foods.  The flight to Arkansas was quite eventful – but more about that later.  It was an extremely successful event on the scale of a district level Code Camp.   There were eight tracks with about 50 presentations throughout the day.  Presenters came in from all over – Georgia, Texas, Ohio, Minnesota are the states I remember – and the presentations were uniformly excellent.  There was also a large Microsoft presence at the event – much larger than we get at the usual Code Camp – which simply added to the fun.  There were approximately 250 attendees – all Tyson employees – and almost every session was recorded, so anyone who missed the event can play them back later.

Special congratulations should be given to Devlin Lyles of Tyson for his central role in organizing this conference and promoting it internally.  He was able to make the business case for the conference to his internal management, arguing that bringing a conference in-house would ensure that everyone at Tyson corporate could participate and, furthermore, exposure to sophisticated conversations about technology will raise the level of software development within the corporation.  I wish more companies were this insightful about, first, the need to raise everyone’s game and, second, that there are easy, non-coercive ways to do this.   Congratulations also to Jay Smith, Jeremy Sharp, Rob Tennyson and all the others who put in long hours to make this conference successful.

I was also happy to have the opportunity to get to know some of the other speakers, in particular Jim Holmes, Phil Japikse, Cory Smith, Tim Rayburn, Robert Boedigheimer, Chris Patterson, Seyed Hashimi, Betty Leudke and Tom Sanchez.

I gave three talks at the TDC: Architecting WPF for Versatility, Intro to WPF, and Advanced C#.  The last talk was mostly code, so I have only attached the slide decks for the first two.

As I said, the flight to the conference was eventful.  I met up with Phil Japikse and Jim Holmes at the airport, recognizing Phil from his MVP profile picture (there aren’t that many MS MVPs with shaved heads and handlebar moustaches).  Our flight kept getting delayed and moved from gate to gate, and we kept emailing Devlin to let him know that we were not confident we would make the speaker dinner.

tdc Phil and Jim

We finally embarked onto one of the smallest commercial planes I have ever had the pleasure of flying in.  There was one stewardess and one pilot and before we knew it we were off.  About half-way between Atlanta and Northwest Arkansas our stewardess came to the front of the plane and asked – I never thought I would ever hear these words — “Is there a doctor on the plane?”  It was cliché but effective in getting everyone’s attention.

As if going down a well-rehearsed list, she then asked if there was a nurse on the plane.  Finally, she asked if there was an EMT on the plane and Phil raised his hand.  Two seats behind me, a passenger was having some chest pain.  Over the course of the flight, this passenger proceeded to pass out twice and projectile vomit once.  That familiar smell was with us over most of Arkansas.  Phil had a commanding presence and immediately recruited Jim to be his assistant.  Jim, in turn, helped to calm the other passengers and simply did a great job keeping his head through the emergency (at the conference he presented a session on Leadership which I am glad to hear was very well attended).  As Phil became aware of the seriousness of the troubled passenger’s condition, he told the stewardess to tell the pilot to land the plane immediately and have an ambulance meet us.  We were close enough to our destination that we simply sped up and quickly dropped our altitude (it took hours for my ears to finally adjust after that) and I don’t think I’ve ever landed and been taxied to the airport gate so quickly.

I already knew that Jim and Phil were impressive software people who can quickly debug and deploy applications during software emergencies.  I was quite pleased and impressed to find out that their skills translate so well to emergency situations in the real world.  They were both heroic and I am quite certain that their actions saved a life that day.

That Wild and Crazy Dynamic Type

I had a mind-blowing weekend playing with the ExpandoObject in C# 4.0.  When an article appeared on MSDN about it prior to the release of Visual Studio 2010 Beta 2, it looked interesting but not particularly useful.  The ExpandoObject appeared to be merely a property bag that was useful in limited circumstances in which the program flow is aware of the properties being added.  The ExpandoObject is, in essence, a property bag (and also a method bag?) that pretends to be a real type.  With the Beta 1, I tried to bind a WPF Window to it and was quickly disappointed to find that WPF just treated it as a dictionary (which is what it really is) rather than as the typed class it is pretending to be.

With the Beta 2, however, this changed.  The WPF binding stack had apparently been modified to recognize the ExpandoObject and to treat it on its own terms.  If I have a binding on a TextBox in WPF to an arbitrary property called, for instance, “Name”, all I have to do is add that string to the ExpandoObject’s internal dictionary and the value I added will show up in my TextBox.  Even better, the ExpandoObject automatically supports INotifyPropertyChanged on that new pseudo-property.

           dynamic Employee = new ExpandoObject();
           Employee.Name = "Jim Henson";

This small change makes the ExpandoObject suddenly very useful, especially in situations where we need a glue layer between servers and clients that are indifferent to static typing such as an object layer between a REST service and WPF.

Phil Haack has a playful post about this aspect of programming with the dynamic type on his blog: http://haacked.com/archive/2009/08/26/method-missing-csharp-4.aspx .  He prefaces it with this:

Warning: What I’m about to show you is quite possibly an abuse of the C# language. Then again, maybe it’s not. 😉 You’ve been warned.

There’s a lot of truth in this.  On the one hand, dynamic types goes deeply against the grain of anyone who has programmed in C# for the past several years.  I’m not sure how this feels to VB developers who always have had the option to turn Option Strict off in their code.  It gives me the heebie-jeebies, though.

At the same time, it looks extremely fun.  Maybe even a little subversive. I want to start finding applications for this new code feature for working within C# rather than simply using it for interop with supported dynamic languages.

The ExpandoObject does some rather cool things not initially obvious.  For one thing, I can add methods to it as well as properties.  This can be done by passing a delegate to it that references a lambda statement, for instance:

        dynamic obj = new ExpandoObject();

        obj.DoSomething = new Func<string>(() => 
            { Console.WriteLine(DateTime.Now.ToLongTimeString()); return "Hello"; });

        obj.DoSomethingWithParams = new Func<string, bool>((x) => 
            { Console.WriteLine(DateTime.Now.ToLongTimeString());  
                Console.WriteLine(x); 
                return true; 
            });
        Console.WriteLine(obj.DoSomething());
        Console.WriteLine(obj.DoSomethingWithParams("something different"));

Another thing it can do is load properties dynamically (loading a dynamic type dynamically, yeah!) by simply casting it back to the dictionary it really is internally.  Here’s a sample of dynamically loading up an ExpandoObject based on an XML Document:

           XDocument root = XDocument.Load("Employee.xml");
            //convert xml document into an ExpandoObject
           dynamic Employee = new ExpandoObject();

           var EmployeeDictionary = Employee as IDictionary<string, object>;
           foreach (XElement el in root.Elements())
            {
                    EmployeeDictionary.Add(el.Name.LocalName, el.Value);
            }

I now have an object that I can bind to the DataContext of a WPF Window.  I could, of course, have just bound the original XMLDocument to my WPF, but then I wouldn’t have nice extras like INotifyPropertyChanged that I normally expect to have at my disposal in WPF development.

The Dynamic Type is a complicated beast however.  Just reading over Bill Wagner’s post on implementing a Method Bag fills me with anxiety: http://msdn.microsoft.com/en-us/library/ee658247.aspx

That post was nothing, however, compared to this gem I found on Nikhil Kothari’s blog from over a year ago!  http://www.nikhilk.net/CSharp-Dynamic-Programming-REST-Services.aspx

Mr. Kothari builds a class that can point to multiple (and, thanks to the Dynamic Type, interchangeable) REST services and generates properties based on the XML or JSON that comes back.  It does much more than this, also, I think, but Nikhil Kothari is so far beyond me that I have trouble understanding everything that is happening in his code.

The source code, by the way, doesn’t actually compile as it is currently written – but then he did this over a year ago, so…

In any case, walking through and coming to terms with what he has created is certainly one of my goals for November.  It is an implementation that is a game-changer for C# development, and raises Dynamic Types from an oddity to something that will actually solve architectural bottlenecks … at least, I think it does.  As I said, I don’t actually understand it, yet.

October 2009: The Month that Was

WorldOfTomorrow

At the Atlanta Leading Edge Microsoft User Group (ALEMUG), we typically set aside some time at the beginning of each meeting to discuss the hot topics related to software development – with a particular slant toward the Microsoft world – that have come up in the previous month.

The web of cross-conversations on blogs, YouTube videos, and software announcements makes up and propels the culture of the software industry.  To be a software developer, in some degree, means being current on these ephemeral Internet happenings.  The purpose of the ten minutes we set aside at the ALEMUG meetings to discuss them is simply to make sure everyone is caught up on current events, so to speak, so that we have a common vocabulary when discussing technology and software methodologies.  After all, communication is the most difficult thing about developing software.  Many of us know how to get things done, but the hard part – explaining why we do things the way we do and sharing our technical knowledge with others – is elusive.  Programming knowledge is always fragmentary, at best, and trying to bring it all together through best practices and even some historical perspective is a constant struggle.

These monthly wrap-ups also serve as a time capsule, however.  A peculiarity of working on the cutting edge of technology is that there is very little awareness of the passing of time.  Software development usually occurs in a bubble of hyper-focus that inevitably destroys our sense of time.  For instance, how long has WPF been around?  How long has twitter been around?  On a resume, what is the longest amount of time a developer can legitimately claim to have worked with .NET? 

With the goal of restoring the sense of the flow of time – what Kant called inner sense – here is a list of matters momentous and trivial to the software industry in the middling period between September and October, 2009:

A renewed debate between Morts and Architect Astronauts was started by Joel Sposky:

http://www.joelonsoftware.com/items/2009/09/23.html

http://jeffreypalermo.com/blog/debunking-the-duct-tape-programmer/

http://martinfowler.com/bliki/TechnicalDebtQuadrant.html

This was mirrored by a similar sort of debate concerning software methodologies started by Ted Neward:

http://blogs.tedneward.com/2009/10/12/quotAgile+Is+Treating+The+Symptoms+Not+The+Diseasequot.aspx

http://haacked.com/archive/2009/10/13/software-externalities.aspx

Microsoft started a new series of ads for their operating systems: Win 7 and Mobile 6.5, that did not quite hit their mark:

http://www.bing.com/videos/search?q=microsoft+launch+party&docid=1316730503766&mid=893DA2AD882B75E7525B893DA2AD882B75E7525B&FORM=VIVR7#

http://www.youtube.com/watch?v=mUotyelWmFE&feature=player_embedded

As the Gartner group weighed in on Win 7:

http://blogs.zdnet.com/microsoft/?p=4227

In hardware, solid state drives got the seal of approval from Jeff Atwood while Barnes & Noble finally came out with their alternative to Amazon’s Kindle:

http://www.codinghorror.com/blog/archives/001304.html

http://gizmodo.com/5380942/barnes-and-nobles-e+reader-like-a-kindleiphone-chimera-first-photos-and-details

Interesting new software and services were released, including a tool for writing iPhone apps using C#, Google Wave (does anyone have an invitation they can send me?), and Yahoo’s alternative to Twitter:

http://monotouch.net/

http://wave.google.com/help/wave/closed.html

http://meme.yahoo.com/home/

An indication that the cold war between Microsoft and Google is beginning to heat up:

http://msmvps.com/blogs/jon_skeet/archive/2009/10/01/mvp-no-more.aspx

And some insights into the world of publishing software books:

http://beginningruby.org/what-ive-earned-and-learned/

Have I Mentioned the Tea?

Fuzi Miao 001

While in China, I had a short list of things I wanted to do, some of which I was able to accomplish and some of which I was not. 

I wanted to see Sun Yat Sen’s tomb (check). 

I wanted to go to the Mid-Lake Pavilion Teahouse in Shanghai because it shows up in both Neal Stephenson’s Diamond Age — in which it is one of the two main hangouts for the mysterious Dr. X along with KFC — as well as Qiu Xiaolong’s Death of a Red Heroine (unchecked). 

I wanted to track down the location of the old Russian Saint Nicholas Cathedral, which I believe was the cathedral where St. John of Shanghai and San Francisco –- a Serbian monk who eventually became a bishop and a saint venerated in America by the Russian émigré community – served (unchecked).

I wanted to try certain Chinese delicacies including fermented (through burial) duck eggs and shark fin soup (check).  The latter particularly impressed my nine-year-old son, a fan of the Japanese show Iron Chef.  

Finally, I wanted to taste and ideally purchase some Dragon Well Tea.  I had first heard of Dragon Well a few years ago when I came across a long article about it in the New Yorker – or it might just as easily been The Economist, Harper’s, since I cannot find any reference to the article on the Internet.  As I remember the article – or perhaps as I remember remembering it – it involved the obscure history of the tea, the peculiar manner in which it is harvested – once a year in spring, under a new moon, handpicked by virgins – and the devotion it has acquired among tea connoisseurs, with some sacrificing a year’s salary in order to purchase a few grams of the highest grade of the long jing leaf.  And so I’ve carried this story around in my head for many years, wondering if I would ever have a chance to taste this particular brew.

Fuzi Miao 009

I should point out that I am not any sort of tea connoisseur, myself.  I suspect I may even be a philistine when it comes to teas, my palate already distorted and ruined by years of coffee drinking.  Nevertheless, I knew that I wanted to try this tea, purported to be the greatest tea of China.

When the moment finally came, it was not anything revelatory.  The tea is, quite frankly, nice.  It has a beautiful grassy aroma and a pleasant, gentle flavor with very little bitterness.  I’d drink it again.  I could certainly see why the tea is considered to be special, but the experience was not like my first encounter with a $300 bottle of red wine in the south of France or my first mug of cold Czech beer in Prague.  Of course, I was not tasting the highest grade of long jing, which needed to be acquired back in spring – and in truth have no guarantee that the tea is even from Zhejiang Province, much less the West Lake region – though the package is marked with the official state PGI label. 

Fuzi Miao 010

In any case, drinking it at home, long jing cha has grown on me.  The smell of it immediately soothes me and the experience of drinking it requires a suitable and respectful ambience – a quiet and clean space with, ideally, a view.  The tea has not given up its secrets to me yet, but I intend to be persistent.

Ah!  But I forgot to tell you about the buying of the tea!

My Chinese colleague and I were passing a Ten Fu Teashop – one of a chain of over a thousand in China – in the Fuzi Miao and heard several young ladies, none older than 17, singing out to us and beckoning us in.

Fuzi Miao 008  Fuzi Miao 002

Upon entering Ten Fu, one of the ladies took us to a special tasting table.  The table had a smaller special wooden table on top of it with slots to catch and drain away any spilled tea.  Here the hostess went to work intricately preparing the tea for us.  I had trouble following all of her hand motions as water was brewed, then poured into receptacles, then disposed of, then poured from one receptacle to another until the hot water finally touched tea leaves. 

Fuzi Miao 003  Fuzi Miao 004   

All the while the hostess described the particular qualities of the teas she was preparing while also suggesting how they should be drunk, at what time of day, and what sort of meals they would go with.

Fuzi Miao 015  Fuzi Miao 007

When the water was poured into the cup that contained the tea, the hostess began brushing it with the lip of the cup, guiding the tea leaves this way and that along the surface of the water as she told us the history of each tea we would be tasting.  This lasted for perhaps thirty seconds and then the tea was strained into yet another receptacle.

Fuzi Miao 012  Fuzi Miao 006

From here it was finally poured into our tiny tea cups.  She then picked up my tasting cup and dumped the contents out.  The first pour was to warm the cup, only.  A second pour and I was finally allowed to taste.  By this time, the whole experience of watching the tea preparation had already overshadowed the actual tea itself.  Did I mention that the hostess was flirting with us the whole time?  We sipped our tea and asked for more.  When the hostess asked us if we would like to try another tea, we could not bring ourselves to leave for dinner as we had originally planned.  And so the whole intricate process started all over again.  The graceful hands of the hostess flitted over the various appurtenances of the tea ceremony as she smiled, laughed, scolded, cajoled, and mocked us in a fluid delivery that had us hanging on her every word – none of which I actually understood.

Fuzi Miao 017

At last we had tried three different teas — which I could barely tell apart until the oolong with osmanthus came along — and when it was clear that we would be purchasing nothing beyond my bag of Dragon Well Tea, we sadly parted ways with our hostess.  When we asked her for her name, she laughed at us and said she couldn’t possibly tell us since we had only just met her, and that we would have to come back to her many more times before she would reveal it.