Life and code.
RSS icon Email icon Home icon
  • Continuations Are Worth Being Hot

    Posted on May 22nd, 2006 Brian No comments

    Steve has noticed, via Don Box, that continuations are getting popular. I can tell you from personal experience that there is a ton of value to continuations in multiple arenas, not the least of which is web serving.

    Apache Cocoon has supported continuation-driven application flow for its web applications for quite some time now, either using Flowscript (ECMAScript with continuations, done in Rhino), or via JavaFlow (which is currently beyond my ken). Flow makes it amazingly easy to model complex behavior using the standard programmer-friendly syntax of loops, conditionals, and function calls. It’s brilliant!

    And in some other work I’m doing right now, I desperately wish for continuations in C#. I am attempting to asynchronously decode buffers into message structures, and the painful callback-based approach used by .NET’s Begin/End/IAsyncResult approach makes it extraordinarily difficult to code. In order to avoid blocking a thread, I am forced to either stitch together a confusing chain of callbacks, or read data in a larger blocks. The problems with the former are lack of understandability and difficult debugging, and the problem with the latter is that message parsing often requires small chunks to be read to determine how much more is to be read to complete the message.

    I yearn to be able to write code like the following, despite my unwieldy made-up syntax and lack of error checking.

    Message Decode(Stream stream)
    {
       BinaryReader reader = new BinaryReader(stream);
       Message msg = new Message();

       msg.Foo = Continuation.CallWithCurrent(reader.ReadInt32);
       msg.Bar = Continuation.CallWithCurrent(reader.ReadInt32);

       return msg;
    }

    Then, the BinaryReader would support something like this:

    void ReadInt32(Continuation continuation)
    {
       // Set in the constructor.
       this.stream.BeginRead(this.buffer, 0, 4, delegate(IAsyncResult result)
       {
          this.stream.EndRead(result);
          int result = this.ConvertBufferToInt32();
          continuation(result);
       });
    }

    I could write my deserialization function as a nice procedural list of instructions, and not have to worry about blocking a thread while I wait. You could, of course, push the continuation call farther down the stack into the stream or socket or from whatever is being read.

  • Fun With C# 2.0 Iterators

    Posted on March 1st, 2006 Brian No comments

    In the little free time that I have, I have been messing around with writing a .NET program to help me with the large amount of photo metadata editing I want to do on all the photos I’ve been uploading to my Flickr photostream.

    It’s been fun doing some .NET again. It’s easy to forget how nice of a language C# is especially with all of the fancy new features 2.0 brings. Last night, I came up with a fun little method of using iterators.

    Simple "Add Photo" dialog box Here’s the scenario: I need to collect photo IDs for editing. As a simple solution, I have a very small dialog box that contains a text field, an “Add Another” button, a “Done” button, and a “Cancel” button. When the user clicks “Add Another,” I want to save the entered photo ID and re-display the dialog. If they click “Done,” the currently entered ID should be saved, and the dialog should vanish. Finally, if they click cancel, the current ID does not get saved, and the dialog disappears.

    I have set up the DialogResult of the “Done” buttton to return with DialogResult.OK, and “Add Another” to return with DialogResult.Yes. Here’s the code in the UI controller responsible for coordinating this:

    public IEnumerable GetPhotoIds()
    {
    AddPhotoDialog dialog = new AddPhotoDialog();

    DialogResult result = dialog.ShowDialog(this.parentWindow);

    while (result == DialogResult.Yes || result == DialogResult.OK)
    {
    yield return dialog.PhotoId;

    if (result == DialogResult.OK)
    {
    yield break;
    }

    result = dialog.ShowDialog(this.parentWindow);
    }
    }

    Then, in the top-level UI controller, I can simply do:

    AddPhotoUIController controller = new AddPhotoUIController(this.mainForm);

    foreach (string photoId in controller.GetPhotoIds())
    {
    PhotoInfo info = this.FlickrApi.PhotosGetInfo(photoId);
    this.CurrentBatch.Containers.Add(new SinglePhoto(info));
    }

    Pretty slick. I wish they had made this feature more general, though, and implemented full-on continuations.

  • WS-Goldylocks & The Seven Layers

    Posted on October 15th, 2004 Brian No comments

    I’d like to comment on Steve‘s post on the WS-* standards process, specifically on how the standards have been produced. A “real” standards process may or may not add any significant value to any given standard. Quite frankly, it depends a lot more on the people involved than anything else. What a “real” process certainly adds is a lot more time until the standard is released. Almost by definition, standards are required to be the least common denominator of functionality, and deriving that LCD is hard work. But the world of web services is amazingly fast-paced. It seems like XML was just barely gaining its foothold in people’s brains and suddenly people were talking about SOAP and services. After that, we jumped into warp speed with everybody and their brother suddenly working together on WS-Security, WS-Trust, and all the others. And as Steve points out, while the standards may not be “real,” they are real enough that different vendors bits can talk to one another.

    All of this reminds me of my college networking class. Frank taught us about the 7-Layer OSI Model for networks (what Chris joking refers to as “The Burrito”). The OSI Model was hashed through and arduously toiled over by the major industry players until it was agreed upon by all. And afterwards, there was much rejoicing!! Now everybody could understand how networks were to be constructed, and a new era of interoperability was born!

    And then Frank told us to forget about the OSI Model. Nobody used it. The standard had been stillborn. While the industry had been fighting, the ARPANET, using a much simpler model, had proven Good Enough. It was so Good Enough, in fact, that it eventually became the Internet that we all now know and love. Nobody uses any other kind of network!

    The moral of the story is that Good Enough running code will usually produce a de-facto standard that will trump everything else. Why bother with a full standards process for the Web Service languages? They are Good Enough as it is, despite the myriad of pitfalls we are sure to uncover in the future. And I have full faith in the community of developers to continue to produce such de-facto standards provided corporate politics and short-term profit are not allowed to trump the engineers’ best judgements.

    Read that again.

    The community of developers will continue to produce such de-facto standards provided corporate politics and short-term profit are not allowed to trump the engineers’ best judgements.

    Be careful. It’s already happening. Some of the competing WS-* standards, such as WS-Eventing and WS-Notification, seem to exist primarily because companies are competing for control of the specs. Such fractures must be kept to a minimum if collaborative, chaordic engineering is to ever produce de-facto standards as successful as TCP/IP.

    It is a rare environment when Getting Things Done is universally accepted as more important than Protecting Your Turf. We all need to keep the pressure up on the corporate powers-that-be to continue the cooperation that has so far proven very successful.

  • New C# Operator

    Posted on July 27th, 2004 Brian No comments

    How many times have you written a piece of code like this?

    public void Jump(string msg)
    {
       if (msg == null || msg.Length == 0)
       {
          throw new ArgumentNullException("msg");
       }
    
       // Jump!
    }

    I don’t know about you, but I write code like this all the time. It’s an important sanity check, and Microsoft recommends it. But what happens if you change the name of the variable msg? Suddenly, your code is wrong. Sure, it’s syntactically correct and will compile just fine, but there is no longer a semantic link between the message returned by the ArgumentNullException and the code from which it was thrown.

    I propose the addition to the C# language of the nameof operator. Analagous to the existing typeof operator, the nameof operator will return the name of its operand as a string. The example from above, then, would be rewritten as follows.

    public void Jump(string msg)
    {
       if (msg == null || msg.Length == 0)
       {
          throw new ArgumentNullException(nameof(msg));
       }
    
       // Jump!
    }

    It is important to note that the operand is still a full-fledged symbol. Thus, in the example above, changing the name of the msg parameter will cause a compile-time error if the operand to the nameof operator is not also changed.
    The nameof operator will simply be syntactic sugar, and requires no changes to the CLR, and therefore also causes no change to the run-time performance of the code.

    Why is this important? After all, the above example is simplistic, even though it is a common case. First of all, there are many more complicated cases that can occur. As we all know, detailed error messages can go a long way towards helping troubleshoot and debug problems in our code. My own personal guidelines for creating error messages are:

    1. Error messages must be unique to a given error condition. You should never copy-and-paste error messages unless the root cause of the error really is identical; and in that case, you should think about refactoring your code because it sounds like you have some code duplication. (The exception to this (pun intended) is the catch syntax, which requires multiple blocks to catch exceptions that do not have the same root.)
    2. Error messages must have a detailed message explaining cause of the problem, including the names and values of any variables used to calculate the error condition.
    3. Error messages should include a description for how to correct the problem. This could be as simple as giving example known-good values, or it could be as complex as describing how to fix your Windows certificate store to have the right permissions.

    The nameof operator will go a long way towards ensuring consistency between error messages and code.

    The other need for the nameof operator is the increasing intelligence of the development tools. Refactoring tools have are quite in vouge, evidenced by the fact that Whidbey will be shipping with such tools bundled in. As we continue to do less and less manual editing of our code, relying on a developer’s eye to find and fix such problems becomes more and more dangerous.

    I came up with this idea when I was at Avanade working with Steve, but I’ve never mentioned it publicly. As I recall, at that time, Steve had the opportunity to have a quick chat with Anders Hejlsberg, the lead designer of C#, and he mentioned this. I seem to recall he liked the idea, but it was one of those little things that would probably never happen. Steve, am I making this up?

  • Re-De-Compiliation

    Posted on July 3rd, 2004 Brian No comments

    I was able to successfully de-compile and re-compile my MoleMan executable using FileDisassembler. It has a few problems generating incorrect code, although I assume that has more to do with Reflector’s de-compilation API than the plugin itself. Mostly, they centered around implicit operators, although it also forgot to add several necessary using statements.

    Overall, I’m very pleased. Now I just have to go through and re-name variables and such to something less nonsensical.

  • Need a Decompiler

    Posted on July 2nd, 2004 Brian No comments

    When I was still at Avanade, I wrote myself a little program called MoleMan to manage my SSH tunnels. It was really useful because I would often disconnect from the wired network and go wireless, and I wanted my tunnels to automatically re-connect. However, when I left the company, I accidentally left the source code on my laptop, which got wiped. All I had left was my binary install of the latest version that I had installed at home.

    Fortunately, I had sent my friend Greg, of Neko fame, a copy of my source code a few weeks earlier. Well, there are a couple of bugs in MoleMan, and I want to fix them and release the program to others who might find it useful. Unfortunately, I have discovered that I made some major changes to the program between the time I sent Greg the source and the final version I’m running. So I need a decompiler.

    I found a good list, but unfortunately none of the free tools will do an entire assembly in at once. And everything else is not free.

    Does anybody know of a good, free C# de-compiler that will do entire assemblies at once? If so, please let me know.

    Update: I have discovered the FileDisassembler plugin for Reflector. Contrary to the name, it actually does de-compile, and it seems to generate pretty good code. I’ll start from here and see how it works.

  • Patching DotNetMock

    Posted on May 19th, 2004 Brian No comments

    I have been working on a project at home for which I am using DotNetMock to create mock objects for my unit testing. Unfortunately, DotNetMock has a couple of problems with its dynamic generation features. The first is that it does not currently support methods on inherited interfaces, and the second is that it does not work correctly with non-primitive value types.

    So I fixed those two problems. Hopefully my two patches will get rolled in.

    DotNetMock seems to be the extension of NMock. Many of the interfaces are the same, and NMock hasn’t been updated since last May. However, there seems to be only one guy on the DotNetMock project, so I’m not sure how long-term the project is.

  • Nasty Error Upgrading to Mono 0.30.1

    Posted on February 16th, 2004 Brian No comments

    Blorg!! I’m trying to upgrade to Mono 0.30.1 (from 0.28) on samus, and it fails during the emerge with a nasty little error (found in the full text). It seems to stem from the fact that the build process is attempting to call the resource generator with the installed runtime, rather than the one it just built. I’ve unmerged the existing runtime and and attempting to emerge again in the hopes that it won’t get confused if there isn’t a runtime already installed.

    Update: So that fixed it. Who knows if that was really the problem or not, but I was able to successfully emerge the package after I had unmerged it. Now to get Dasblog running…

    ** (/usr/bin/monoresgen.exe:21345): WARNING **: cant resolve internal call to "System.Type::IsInstanceOfType(object)" (tested without signature also)
    
    Your mono runtime and corlib are out of sync.
    Corlib is: /var/tmp/portage/mono-0.30.1/work/mono-0.30.1/runtime/mscorlib.dll
    
    When you update one from cvs you need to update, compile and install
    the other too.
    Do not report this as a bug unless you're sure you have updated correctly:
    you probably have a broken mono install.
    If you see other errors or faults after this message they are probably related
    and you need to fix your mono install first.
    
    Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required
    in (unmanaged) System.Type:GetTypeFromHandle (System.RuntimeTypeHandle)
    in  System.Threading.Thread:get_CurrentCulture ()
    in  System.Globalization.CultureInfo:get_CurrentCulture ()
    in  System.String:ToLower ()
    in  .ResGen:GetReader (System.IO.Stream,string)
    in  .ResGen:CompileResourceFile (string,string)
    in  .ResGen:Main (string[])
    

  • Decompiler Obfuscated

    Posted on February 2nd, 2004 Brian No comments

    Oh the irony! I am definitely sad to see that Lutz Roeder has decided to obfuscate Reflector. Reflector is a great tool for exploring an assembly, discovering work-arounds for defects in APIs you can’t control, and poking at code for possible useful but undocumented types and methods.

  • XSD As A Type System Redux

    Posted on January 26th, 2004 Brian No comments

    Steve has written a lot over the last few days on his belief the XSD is not a type system. This was one his favorite topics to toss around with me when we were both at Avanade. If you haven’t read his disserations, you should check out Part 1, Don Box‘s reply, and Steve’s Part 2, in reply to Don. It’s all great.

    I find that I tend to side with Steve’s position that XSD is not a type system. Although it can be used as a type system, it really is much more powerful at not being a type system. If you are using it as such, you should really be using something simpler than XSD, like .NET’s common type system. It describes types much more succinctly. A parallel might be C++ to C: C++ is an object-oriented language with object-oriented features. You can code C++ so that it degenerates to not being object-oriented, but you’d be missing out on a whole heckuva lot. Now, this discussion is interesting and all, but it’s not what this post is really all about. This was the background to set up a higher-level question that came up while I was having coffee this afternoon with Corey and Chris.

    We’ve been beholden to a statically typed language for this entire discussion, and it has been forgotten that an entire realm of dynamically typed languages exist out there, and I believe they render the entire discussion meaningless. Langauges like ECMAScript, Ruby, or Python. Take ECMAScript, for example: It’s dynamically typed, and the concept of a class only exists in-so-much as each object is its own class. Equality is based strictly on structure. In such a language, the idea of a nominal type is pointless, and therefore such a language can always parse any given XML structure and create a type at runtime to represent that XML. It doesn’t matter whether the schema validates or not as long as the XML is well-formed. It seems to me that the robustness provided by the dynamic typing makes it a near-essential feature for writing flexible, resilient consumers and services. Certainly it cannot be worse than requiring re-generation of some proxy classes at build time. I am beginning to think that this entire is-it-a-type-system discussion is irrelevant in the face of languages that neither use nor require a type system.