The Programmer Phases of Grief: or Language Translation is Harder Than It Looks
One's mind should be pretty clear when programming. I'm a decent enough programmer, but I'm not a bad-ass programmer. At least not anymore.
Back in the day, before marriage, before diabetes, before babies, when I was sleeping a full 8 hours, I could code some nice stuff. Now it's just a miracle it compiles. When it does.
I also tend to, um, not think. At all.
I have been looking into OpenID lately, and had the privilege of meeting the CEO of JanRain, Scott Kveton (pronounced 'k'-vee-ton', but real fast, like the first two syllables are one) and mentioned that I was pleased they had made a .NET compatible OpenID library available (Andrew Arnott has wrapped it in a nice ASP.NET 2.0 Web Control).
I was thinking I'd add OpenID support to Corillian's Voyager eFinance Server as a Proof of Concept, as our authentication system is pluggable. It'll be a nice demo, as our CardSpace one already works great.
I went and download the .NET OpenID Library preparing for a few hours of tedious work.
The .NET OpenID library is written in Boo - I blogged about Boo in 2005 (I wonder if Ayende will update his Boo Reflector support for Reflector 5.0?) - which is a language that is damn-near Python. You can convert your code to Boo with this online tool if you want to play. Here's some Boo examples versus C# 2.0.
Right now the best and easiest way to write Boo is to use SharpDevelop, the Open Source IDE. Boo is a first-class language within SharpDevelop, along side VB and C#, and includes all the usual good stuff like debugging and what-not.
The OpenID .NET Library, as I said, is written in Boo, very likely because the original library was written in Python and Boo offered not only a clear porting direction, but also made the developer comfortable. More on this later.
I figured this evening I'd "port" the Boo source for this library over to a "proper C# library" so the masses wouldn't have to sweat Boo. This experience let me through the...
Phases of Programmer Grief*.
I was of course, like any
religious zealot C# programmer, shocked and offended and looked on with disbelief that anyone would use any language that wasn't the One True Way® to produce perfectly viable and runnable IL. Microsoft's whole multi-language, single-runtime was just to prove a point to the Java guys right? I looked at the code with disdain
Shock is often accompanied by numbness...
No curly braces? Duck typing? Is this how these people live and code? Freaks. Toy Languages, man, toy languages.
At this point, I don't think it'll be hard to port this. The library includes NUnit Tests, but as the library is structured with a lot of things marked internal to the assembly, there's two libraries. The main one, and the test one - but the code is also compiled into the test assembly. I started marking things public, and separated the two.
I've already missed the forest for the trees here, and I'm happily stepping on butterflies in my quest for the big game.
My goal was to use the Test library, as is, to test my glorious new C# library - the one I hadn't started yet. If the same tests passed on my C# version, shiny. I started poking around the code, trying to get an idea on where to start. The library includes a Server and an Consumer, and since I just needed the Consumer in the short term, I figured I start there.
There's not THAT much code in the consumer, but there's not only a number of utility classes, but there's also a bunch of Boo language-specific collections and such. Also, as .NET 2.0 doesn't include Diffie-Hellman support (Orcas does, BTW), the OpenID library referenced Mono.Security to get there BigInteger class and Diffie-Hellman support.
ASIDE: Be aware that
Mono is GPL'edMono Libraries are MIT X11. Mono produces IL, and Mono libraries are CLS compliant, you can reference them in your Windows .NET applications happily, and they'll work fine 99.9% of the time. Adding a Mono library to my Windows .NET CLR program doesn't make it run under Mono, it's just referencing a library. Some people, like myself (yesterday) look down on this like we look down on C# programs referencing Microsoft.VisualBasic.dll, but hey, it's tested code I didn't have to write...you'll no doubt see my own personal epiphany coming later in this post...
I thought I might write my own Diffie-Hellman...
Note that I'm getting totally off the main task-at-hand already here...but I've not noticed it...yet...
...or find one that was already done. If I could just remove that Mono.Security reference...
I started to feel bad, who am I to remove this library? Someone's worked hard on it, it shipped, let's leave it be, and get to the real work. Maybe I can find a better way to port this...ah, yes, Reflector!
I'm completely delusional...lack of sleep? Analysis paralysis or just complete lack of thought? Ah, too much soda, perhaps? High blood sugar?
I'll just reflector the assembly and decompile it into C#. Heh, maybe I'll use Denis Bauer's FileDisassembler. There's probably some Boo specific stuff, but I'll yank that, no problem. It might be sinful, but no one is looking.
Of course, Boo assemblies include dozens of anonymous generated types and adapters to make Boo's closures work (it was designed before Anonymous Delegates could be used for closures) as well as for type inference.
Gosh...this decompiled C# code isn't even close...this may express the intent to the computer, but it doesn't reflect the Programmer's Intent at all.
Stupid piece of crap Reflector! Man, Lutz can't even decompile to something I can freaking read!
Remember that IL is the applesauce on its way to becoming apple juice. Note that Stupid Scott is pissed here because Lutz's Reflector can't turn applesauce back into an apple. Darn Reflector and the Laws of Abstraction.
Shoot...this is going to take longer than I thought. Now I've got to just freaking write thing whole thing from scratch by actually thinking and understanding what the code is intending to do! Man, I wasn't planning to think tonight, I just wanted to get OpenID on my blog.
I'm not a good programmer! I've been coasting on charm for at least the last three years. I remember what closures were in college, but I've been using .NET 1.1 for the last five years and it dulls the senses...I might as well just give up and become a nurse.
Acceptance and Hope
Wait a second. I've already got a library that works. It's got unit tests. It depends on a tested and released Mono library and a 3 year old non-mainstream language, but it works. It's been used and implemented live before and someone has already wrapped it into an even better and more useful abstraction. Maybe it'll work after all.
The moral of this story is that my time would have been better spent learning Boo, reading the source, and using the Library. The source came with a NAnt Task, but I just created a Boo Project in SharpDevelop - THAT wasn't wasted time.
After I'd learned enough Boo, if I really wanted a C# version, for whatever reason, I should have just written it from scratch using the public interface as a template and the Programmer Intent, written in Boo, as my algorithmic scaffolding. Hindsight is 20/20.
Now, how do I get my evening back?
* With Tongue Placed Firmly in Cheek.
** Image stolen from here.
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
Ah the joys of software development...
I tried to print this in firefox 2.0 but the end of sentences gets clipped at the right margin. I was looking for a "printable version" link...
I hope you (or someone) can fix this since i usually print blogs and read it on the subway home.
Just for clarification. Mono is not "one-thing". It's a set of components (compiler, runtime, class libraries). Each has a different licensing so to say "Mono is not GPL" it's not quite rigth. More details itasca: http://www.mono-project.com/FAQ:_Licensing
There are other licenses that allow a binary library to be linked to without requiring an open-source license for the application (such as the LGPL), but the GPL is not one of them.
Ayende and ChilliCoder - Ah, you're right...thanks...I forgot the libs and compiler are licensed differently.
MikeB - Yes, the libs are MIT X11 it seems.
i've been working on a code base that in some ways is pretty similar to the absolutely wonderful Castle Project. as nice as it is that someone else has written so much fantastic code and has so many great unit tests, its still inordinately difficult decyphering how everything is supposed to work together. all code needs some high level commentary on functionality and design and purpose. i would love to abandon my own scrappings and jump straight to the castle project, but with such motley documentation it would require a massive pinwheeling leap of faith.
As an aside, I really like some of the concepts of Boo. I love that Duck typing is extensible (I can write a C# class that supports Duck typing in Boo via IQuackFoo (a hilariously perfect interface name)). I just wish it could get a makeover for v2.0.
Please join the discussions at the Castle forums and/or mailing list.
The documentation that we have is intended for users of the API, not for people hacking the API.
Your depression statement sounds very familiar.
My buddy and I have the "Depression Comment" stolen directly from Top Gun:
"Hey, do you have the number of that truck driving school we saw on t.v. last night? I think I'm going to be needing that...."
Also, if you google for C# Diffie-Hellman you'll find this library:
Boo is just as fast as C#, but the author of the openid library doesn't seem to realize that any dll or exe you create using boo depends on the Boo.Lang.dll. You can't just copy the dlls from his bin folder, you need the Boo.Lang.dll too. And not just any Boo.Lang.dll, but one that is the same version used to compile the openid dll.
Last year I submitted patches to reduce the boo.lang dependency (use System.Convert class instead, etc.), with the goal of eventually eliminating this dependency, but they were not accepted, boo hoo :)
I'll email JasonA, thanks!
DITTO! This site is impossible to print; to do so I literally have to use view source and reformat it! (or use ClipMarks if I'm in Firefox)
Anyway, glad to see you are start beyond those C# blinders that you've been sadled with. :) Would love to see you delve more into the netherworld of dynamic languages here on Hanselman.com!
Wonderful use the Kubler-Ross Stages of Grief.
But if you think picking up a new language every other year is tough; learning new medications every month will really tax you when you become a nurse. Nursing today is not sitting at the bedside giving aspirin and changing bed pans. Nurses have contact with hospital patients 24 hours each day. Knowing when a change in the patient is part of the disease process or is the start of a downward trend requires strong critical thinking skills. You already know that , Scott; but some of your readers might not.
IT in healthcare is still in the toddler stages. Big corporate and univeristy hospitals have plenty of IT but very little IM. Getting the right information to the right people at the right time is one of the many challenges of the nurse today.
I read for inspiration on how I can help move that information from the bedside to the right person as quickly as possible. Thanks.
Bob Shea, RN
I love the comment "well, I'll just rewrite SVN" above. That's classic. If I find myself saying or thinking the word "rewrite" I am instantly alarmed. At this point, since I am in business for myself, it is more cost effective to simply buy code (or find it for free on the internet) than it is to rewrite *anything*. Maybe I am just getting lazy in my old age.
- Kevin, JanRain code monkey
(although not the particular code monkey who did the Boo port)
p.s. whaddya think, should we use IronPython next time?
Comments are closed.
Peanut butter Cookies: