Steve Yegge’s rather famous post, “Execution in the Kingdom of Nouns” has probably done more to frame and influence my thoughts about object-oriented programming (OOP) than anything else out there. In the discussion thread about my post on multithreading loops, I finally got a handle on why I feel that multithreaded work is significantly more difficult than it needs to be: the noun-oriented nature of the languages that I have written multithreaded code in. Of course, it is entirely possible for there to be an OO language without the focus on nouns (Chad Perrin says that Ruby is one of them, but I have not worked in it). But, at the end of the day, the noun-ness of mainstream OO languages makes multithreading no better than miserable to work in.
A great example of what I am talking about is the code in my VB.Net multithreading series. Look at the code for working with a monitor. This simple example is fairly hard to follow to be honest. By glancing at the code, even someone who knows VB.Net and multithreading fairly well like myself cannot quickly judge what is going on.
Why is this? Because multithreading is an extreme example of what Steve Yegge’s article is about. Multithreading is purely verb oriented, and the objects involved do not need to be. The programmer does not need to be passing about a mutex object, for example. Mutex’s are active across the entire system, so why even bother to pass them around? Why not have a “lock” command and pass it parameters like scope (which would determine whether it used a mutex or a monitor) and the name of the lock, and have the run time environment manage a hashtable of various locking objects? Let’s ditch these semaphore objects and have the language have a “listen for signal” command and a “send a signal” command. Would this be too difficult?
I truly doubt it! The fork() command on UNIX has been around forever. Regardless of your language, using a process fork on the UNIX platform feels the same because it is a base feature of the OS, and various C-style languages all expose that functionality fairly identically if they expose it. Furthermore, System V IPC is already a standardized, verb-based system.
There is already one example of this: SyncLock (that’s VB.Net parlance, it is simply “lock” in C#). SyncLock does a cheap monitor lock against an object that you provide. Sadly, extending VB.Net or C# at the level of creating a new block construct is either very tough or impossible to the best of my knowledge. If it was possible, it would be fairly easy to write a DSL (like LINQ is) to perform multithreading, and then use that DSL within VB.Net, C#, etc. to easily handle the multithreading work without having to explicitly and overtly deal with the .Net Framework’s ugly, noun-oriented multithreading systems. Indeed, SyncLock “feels” really out of place; I cannot think of any other language-level statements in VB.Net that accept any type as a parameter and actually work — even the built-in casting calls like CInt and CStr are limited to certain types; calling CInt on a Bitmap object is a compiler error, not a runtime error.
The problem is that the “Kingdom of Nouns” values conformity over utility. There are some very good reasons for it. If I can demand an exception for multithreading work, then someone else (just kidding, it would be me again) would demand that regex’s be run as an operator the way that Perl does. And then someone else would want their domain-specific functionality to be bumped up to function or operator status. And the next thing you know, we turned C#, Java, or VB.Net into K&R C with a huge set of libraries pre-included. Yuck.
I think maybe what would be better (and this is why I love the .Net CLR) would be to have something similar to LINQ but for multithreading, and write it in a language much better suited for this work. Then, access this DSL in the same consistent way regardless of what language your project is actually in, much as everyone uses the Perl regex syntax now. LINQ is based on closures; doing something similar could very well be the ticket to making the .Net ecosphere a multithreading paradise. (MSDN has a great in-depth article on how LINQ works.)
Interestingly enough, it looks like Microsoft Research is already headed down this path. Let’s do the math here. F# gets more and more mentions from internal Microsoft people. Closures are getting added to VB 9 (in .Net 3.5) because LINQ requires them. LINQ and a rather SQL-like (and therefore, imperative feeling) structure gets added across the .Net board, replacing and improving on a wide scale the concept of “query,” and with it, much of the existing ADO.Net structure. Microsoft has been throwing a good deal of effort behind IronRuby and IronPython. Team Foundation Server, plus the associated tools, can do much of the organizational stuff that OO helps with, in terms of multiple programmers working on the same codebase. Microsoft Research is adding “design by contract” to C# with Spec#, a superset of C#. Add this all up, and it says to me that Microsoft is starting to push very hard against strict OO. Hopefully, Microsoft Research’s TPL will do for multithreading what LINQ is doing to the concept of queries.