|
JOB REFERRALS
|
|
|
|
ON THIS PAGE
|
| ADHD: Good |
| More on the dynamic language wave, ... |
| If I were to write an XML services ... |
| Seattle Code Camp: |
| Props to my wife |
| Thoughts on JAOO 2005 |
| Using the network at 37,000 feet |
| Syntactic sugar |
| Language Innovation: C# 3.0 explain... |
| Build the JDK (on your Windows box)... |
| No, John, software really *does* ev... |
| JavaZone 2005 Presentations |
| Book Review: Rootkits, by Hoglund/B... |
| JavaZone 2005... or, an excuse to w... |
| C-omega's Revenge: Project LINQ |
| Ben learns the difference between "... |
| Installing Vista B1 |
| Of blogging, reviewing, endorsing, ... |
| It's time to do away with this "Web... |
| C#: Is the Party Over? Not to anybo... |
| Best practices, redux |
| Conference tour: Q4 2005 |
| Comment etiquette |
| There is no such thing as "Best Pra... |
| WS-Addressing, the complexity-to-po... |
| Welcome to JSR-277! |
| Adopting Rails... or Ruby... or any... |
| When do you use XML, again? |
| Why .NET developers should learn Ja... |
| Book Review: Pragmatic Project Auto... |
| Parrot interoperability |
| Recommended Reading List (old versi... |
| Rails... finis? |
| More on Rails |
| NFJS Austin, and Rails |
| Starting a new weblog |
|
|
|
ARCHIVES
|
| February, 2010 (1) |
| January, 2010 (4) |
| December, 2009 (1) |
| November, 2009 (3) |
| October, 2009 (3) |
| August, 2009 (2) |
| July, 2009 (4) |
| June, 2009 (3) |
| May, 2009 (6) |
| April, 2009 (4) |
| March, 2009 (4) |
| February, 2009 (5) |
| January, 2009 (11) |
| December, 2008 (3) |
| November, 2008 (9) |
| October, 2008 (1) |
| September, 2008 (2) |
| August, 2008 (4) |
| July, 2008 (10) |
| June, 2008 (5) |
| May, 2008 (10) |
| April, 2008 (13) |
| March, 2008 (11) |
| February, 2008 (18) |
| January, 2008 (17) |
| December, 2007 (12) |
| November, 2007 (2) |
| October, 2007 (6) |
| September, 2007 (1) |
| August, 2007 (2) |
| July, 2007 (7) |
| June, 2007 (1) |
| May, 2007 (1) |
| April, 2007 (2) |
| March, 2007 (2) |
| February, 2007 (1) |
| January, 2007 (16) |
| December, 2006 (3) |
| November, 2006 (7) |
| October, 2006 (5) |
| September, 2006 (1) |
| June, 2006 (4) |
| May, 2006 (3) |
| April, 2006 (3) |
| March, 2006 (17) |
| February, 2006 (5) |
| January, 2006 (13) |
| December, 2005 (2) |
| November, 2005 (6) |
| October, 2005 (15) |
| September, 2005 (16) |
| August, 2005 (17) |
|
|
|
CATEGORIES
|
|
|
|
|
BLOGROLL
|
|
|
|
|
LINKS
|
|
|
|
|
SEARCH
|
|
|
|
|
MY BOOKS
|
|
|
|
|
DISCLAIMER
|
Powered by:
newtelligence dasBlog 1.9.7067.0
The opinions expressed herein are my own personal opinions and do not represent
my employer's view in any way.
© Copyright
2010
,
Ted Neward
E-mail
|
|
|
|
|
 Wednesday, October 05, 2005
|
ADHD: Good
|
|
EVer since being diagnosed as an adult with ADD (Attention Deficit Disorder), I've been actually pretty cool with the idea--it lets me multitask far more easily than my non-ADD compatriots, and I've always enjoyed the creativity that goes with an imagination run wild.
Now, apparently, MSN thinks so too.
Wednesday, October 05, 2005 1:31:12 PM (Pacific Daylight Time, UTC-07:00)
|
|
|
More on the dynamic language wave, but leave the poor vendors alone
|
|
The good folks over at Relevance have blogged again, offering something of a backhanded compliment to the new features of C# 3.0:
The argument that I infer from Ted’s piece is "Look! now we can have (some of) the expressiveness of dynamic languages with (most of) the safety of a statically typed language." ... But just because C# now looks a little more like some dynamic languages, don’t make the mistake of assuming that two worlds are converging. In the most important ways, they are as different as ever. Here’s why: Languages like C# "bake in" specific and detailed rules for inheritance, encapsulation, delegation, how symbols are interpreted, etc. In dynamic languages, similar rules exist, but they are not part of the language core. Instead, they are idiomatic extensions built within the language itself. Development teams can follow these idiomatic rules. Or, they can build (and enforce!) their own rules, specifically tailored to their needs. This has huge implications for productivity. In dynamic languages, you get to build the language up toward your domain, while you build the solution down. Well, I'm going to take some umbrage at the inferred argument, in that I would phrase it as "Look! Now we can have some of the expressiveness and flexibility of dynamic languages without sacrificing the safety of a statically-typed language", so I'd say they got it half right. But the idea that a dynamic language doesn't have specific and detailed rules regarding inheritance, encapsulation, delegation, and so forth, is a fallacy: they have them, they're just not the same rules as those for a statically-typed language. Make no mistake about it: if C# or Java wanted to have the ability to support type reification like that supported by languages like Self, it could do so without too much difficulty--code could modify the core type tables in memory, adding methods, removing methods, even hooking in to the basic method execution processing code that the JIT compiler creates on the fly for both environments. The basic truth here is that the creators of the JVM and the CLR didn't believe in such things, and more importantly, didn't believe such things justified their costs in general-purpose programming langauges.
Folks, we need to realize something: all this "expressiveness" is like putting craftsman's tools in your hands; in the hands of a master craftsman, amazing things can result, but in anybody else's hands, it's putting a loaded gun into the hands of a child. YOU may be good enough to be disciplined enough to keep the rules of your types in your head when programming with Ruby, but are all of the programmers on your team equally gifted? Are all of the programmers that will follow you so gifted?
There's something else that they call out here, though, and that's the part that irks me:
So why has the static/dynamic debate staggered on for so long? I think we could get closer to some answers with better choice of terms. "Static" vs. "dynamic" is highly misleading. I propose we use a new set of names: vendor-oriented vs. developer-oriented programming, or VOP vs. DOP. So who do you trust most: vendors or developers? I find this argument highly unfair and totally bigoted. It essentially suggests that vendors can't do anything right, and portrays them in the traditional "corporations are the root of all evil" that right now so deeply permeates the American social landscape. It also portrays everything done by "non-vendors" (whomever they are) as pure and white and good; never mind the ten thousand open-source Web framework projects on Sourceforge that all do mostly the same thing, just with a slighly different vision or API layout. (Quick, somebody tell me something that Ruby can do that ECMAScript can't. Or Cincomm Smalltalk, for that matter.) For crying out loud, guys, get off the Libertarian rally train for a moment and at least cough up some kind of concrete criticism--after all, after all, HTML was defined by evil vendors, too (in the none-too-subtle guise of a "standards committee"), and I don't see us rushing to abandon that any time soon. Nor do I want us to. If you choose to distrust all vendors, then feel free to do so, but riddle me this: if you sell code for a living, aren't YOU a vendor too?
.NET | Java/J2EE | Ruby
Wednesday, October 05, 2005 12:56:59 AM (Pacific Daylight Time, UTC-07:00)
|
|
 Friday, September 30, 2005
|
Seattle Code Camp:
|
|
I'm a bit late to this, but they've just started putting together the logistics for Seattle Code Camp (Oct 22-23), a community-driven event bringing programming speakers and interested attendees together for a couple of days, gratis. Who is "they", you ask? It's that Evil Empire, Microsoft, out to steal your souls. Be warned, Java faithful, lest ye lose your chance at the Afterlife and Good Code!
Not.
Code Camps are a recent invention of Microsoft's, and they're intended to be technology-agnostic. (In other words, no evangelism, no hard-sells to convert you to .NET. As a matter of fact, I think I've heard more anti-Microsoft jokes from the Microsoft Developer Evangelist team than any other organized body, including the JBoss folks.) Microsoft is doing what it can to improve it's relationship with developers on the whole, and this is one of those efforts. It's on the up-and-up, believe me--we had a number of non-.NET/non-Microsoft talks at the Portland Code Camp a few months ago, for example.
I'm the track chair of the Java technology area, for example, and already a friend of mine (whose name I'm not sure I have permission to mention here, so I'll play it safe and not say it, but you'd recognize it if you heard it--he's behind a couple of good XML open-source frameworks, on which he'll be speaking) has agreed to brave the waters and come speak. If you're interested in Java, Ruby, .NET, XML, or anything else code-related, come on by; details of where will be posted soon. If you're interested in speaking at said event--and this is not open to just professional speakers, but anyone with something interesting and code-related to show other programmers--contact me and I'll either put you in touch with the right folks, or (if it's Java-related), it's me you deal with. 
And just for the record, I would LOVE it if the Seattle Java community stormed the show and outnumbered the .NET talks. Email me and let's make it happen. 
|
 Thursday, September 29, 2005
|
Props to my wife
|
|
For those of you who don't know this, the blog at the root of the neward.net domain is one that my wife maintains--all I can claim is inspiration, providing her with plenty of material to write about, like the stories about her kids and her uber-geek husband. A regular Muse, that's me. 
The reason I bring it up here, in this channel, is that I've had more speaker-friends of mine come to me and tell me that while they like reading my blog, they love reading Charlotte's blog. What's more, their spouses find Charlotte's blog to be highly entertaining, probably because they can relate so deeply to Charlotte's dilemma as Geek Widow. So if you've got a girlfriend or wife who'd like to check out a non-technical blog, or if you're looking for a bit more insight into the personal world of Ted, or maybe you just want to read a pretty good writer, check out The Neward Family Weblog.
G'wan--the geek blogs will still be waiting for you when you get back. 
|
|
Thoughts on JAOO 2005
|
|
Whomever designed the JAOO conference should be knighted by the Queen. Or King. Or whatever it is they have in Denmark (forgive my lack of background on Danish monarchist traditions; disturbing for a former International Relations major and future diplomat, I know, but...).
I've got to admit, I'm rapidly falling in love with the European shows--first JavaZone, then JAOO, not to mention SDC earlier this year, it's really becoming apparent that European shows (despite their reputation to the contrary, apparently, an attitude I completely don't understand) are every bit as interesting and exciting as US ones. In fact, I might go so far as to say they're even better than their US counterparts. I'm not certain exactly why, it's just they seem to have more "character" than the US shows I've been to over the years, the sole exception to that being the NFJS shows and DevTeach (which I think has more of a European flavor to it thanks to its Canadian heritage). Organizers of a show in Bergen, Norway, have invited me to their get-together in Bergen in April, and I'm already looking forward to it, not to mention Javapolis in December. Oh, and now that I think about it, DevWeek is coming up, too. 
I don't know if they're worth flying out from the States to go see (not when NFJS brings so much of that same feel to your backyard), but they're definitely fun to speak at, despite the nine-hour or eleven-hour flights from Seattle to Continental Europe. And to those who might suggest that European shows are somehow inferior to US ones... fie! fie! fie on thee!
Conferences
Thursday, September 29, 2005 12:42:37 AM (Pacific Daylight Time, UTC-07:00)
|
|
 Monday, September 26, 2005
|
Using the network at 37,000 feet
|
|
One of my favorite questions to ask during my Enterprise Fallacies presentation is how you're going to use your thin-client application at 37,000 feet, because the airlines don't have network access. Now, as I write this, I'm on board a Scandinavian Air Service flight to Copenhagen (on my way to JAOO), using the wireless service on the flight to access the thin-client blog-entry interface on the site--this wasn't written offline and posted later, as so many of my other blog entries have been.
Which means, of course, that I now face a dilemma--do I retract what I say in that part of the Fallacies talk, and admit that, finally, the network really is available everywhere? After all, even though it's only the European carriers that are offering it (Lufthansa and SAS are the only two I know of thus far), and even then only on their international flights (so far as I know), the actual connection is "Connexion By Boeing", so you know Boeing is going to offer it as a retrofit on US aircraft before too long--it's just a matter of the FAA getting around to realizing that the signal isn't nearly as much of a danger as they've made it out to be.
So, is it time to abandon the first fallacy?
Duh--of course not. 
Truth is, the network access from the plane is horrendous--latency is terrible, which makes a lot of sense, given how far these poor little bytes have to travel in order to actually reach the site. In fact, if you consider the fact that they're traveling through a tight-band satellite connection, which has been known to be somewhat flaky due to nothing more than aircraft movement, it's pretty amazing that they get there at all. But more importantly than that, the point still remains that even if the network is there most of the time, it's not there all of the time, and the partial-failure scenarios that have been with us from the beginning are still scenarios we need to worry about for the enterprise systems that we build. And, more importantly, by taking network outages into the design/architecture of the system, we build not only redundancy in case of accidental failures but also ability to function even in the face of administrative outages (patches, upgrades, hardware replacements, etc).
The First Fallacy isn't just about network availability, it's about network outages, and the more we spread wireless around (and become dependent on it), the more we'll find that network outages are more and more common, something that we'll have to take into account when building systems. So don't expect the First Fallacy to go away any time soon. 
Update: Well, turned out I was more right than I knew; while I was able to surf to the entry page to fill this entry out, I couldn't manage to get it submitted--kept timing out when I'd push the button to send it in. A couple of other States-based sites were timing out, too, so I'm guessing that the gateway (whether that's on the plane or on the ground, I'm not sure) is giving up because the latency is so high. So apparently the First Fallacy is still with us, airplane networking or no. (Interestingly enough, though, MSMessenger and Google Talk worked just fine, so apparently the latency either doesn't bother them or the conversations were just that much slower and I didn't realize it.)
Monday, September 26, 2005 9:13:19 AM (Pacific Daylight Time, UTC-07:00)
|
|
 Thursday, September 22, 2005
|
Syntactic sugar
|
|
Apparently there's been quite a stir started by my use of the term "syntactic sugar" to describe the featureset of C# 3.0, and more than a few people are wondering what I mean by that. Simply this: that the C# compiler isn't doing anything fundamentally *different* than what you could easily do using the existing facilities of the language--in essence, it is making certain things easier, not possible. So, for example, right now the C# compiler does not allow for inline assembly CIL expressions (though I wish it would, quite honestly), so adding this as a language feature would be a non-sugar feature. The implicitly-typed local variable, on the other hand, is just an easier way to declare a local, nothing else changes once the compiler has finished its pass over the keyword "var".
It's probably not the most rigorous definition of the term, and I'm probably using it wrong, but that's the beauty of expressing an opinion--you get to learn just how wrong you are from a variety of different sources. Thank God for the Internet! 
.NET | C++ | Java/J2EE
Thursday, September 22, 2005 2:30:18 AM (Pacific Daylight Time, UTC-07:00)
|
|
 Wednesday, September 21, 2005
|
Language Innovation: C# 3.0 explained
|
|
For those in the Java community who've heard brief rumors about the suggested feature set of C# 3.0 announced last week at PDC, let me be the first to point out that nothing in the language (aside from generics, which Microsoft did right in C# 2.0, integrating them into the virtual machine rather than the type-erasure-based approach that Java chose) that's proposed couldn't be done in the Java language or on top of the JVM; in fact, most of the features of C# 3.0 are, arguably, nothing but syntactic sugar designed to make programming more productive. What I plan to do here is explain each of the features of C# 3, show how they're implemented (by examining the generated CIL), at least in the PDC preview Microsoft handed out at PDC, and by doing so demonstrate how Java could be extended in turn to support exactly the same sorts of features.
Standard disclaimer applies: all of this is based on the PDC preview of C# 3.0, no guarantees or warranties implied, use at your own risk, yadda yadda yadda. In short, if you install it, and it blows up your hard drive, it's your own fault. 
Implicitly typed variables
For starters, C# 3.0 will support implicitly typed local variables, meaning that programmers can now write code in a more "ignorant" fashion--programmers need not worry so much about getting the types exactly correct when working with local variables:
var i = 5;
var s = "This is an implicitly typed local variable";
var a = new int[] { 1, 2, 3 };
It's important to realize here that these are not "var" types in the JavaScript sense, but are in fact statically-typed references whose type is inferred by the compiler instead of explicitly declared by the programmer; in essence, the code that's generated is the same as if we'd written:
int i = 5;
string s = "This is an implicitly typed local variable";
int[] a = new int[] { 1, 2, 3 };
We can verify this by running the code through the C# compiler and examining the resulting IL:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 28 (0x1c)
.maxstack 3
.locals init (int32 V_0,
string V_1,
int32[] V_2)
IL_0000: nop
IL_0001: ldc.i4.5
IL_0002: stloc.0
IL_0003: ldstr "This is an implicitly typed local variable"
IL_0008: stloc.1
IL_0009: ldc.i4.3
IL_000a: newarr [mscorlib]System.Int32
IL_000f: dup
IL_0010: ldtoken field valuetype
'{E4ADF86B-1985-4CA3-90AF-B705A8279423}'/'__StaticArrayInitTypeSize=12'
'{E4ADF86B-1985-4CA3-90AF-B705A8279423}'::'$$method0x6000001-1'
IL_0015: call
void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_001a: stloc.2
IL_001b: ret
} // end of method Sample::Main
Notice the .locals directive? For those not familiar with IL, that's the declaration of the local variables in the method, and as you can see, the three locals (named V_0, V_1 and V_2) are declared to be of type int32, string and int32[], respectively--the compiler inferred those type values from the literals assigned to them. Which means, correspondingly, since the compiler has to infer the type values, we can't have an implicitly typed local variable without some sort of hint as to what type it should be--therefore, no uninitialized "var" types are allowed.
It may seem odd and a trivial feature to add, but this will turn out to be a profound feature of the language when coupled with object initializers, next.
Object initializers
One of the more annoying aspects of C# (and Java, or C++ for that matter) is that we end up having to write a lot of redundant code, particularly when frequently it's all effectively the same basic conceptual idea. One such area of redundancy is constructors--far too often, we write classes whose constructors do the most basic thing a constructor can do, which is of course to initialize its fields to their desired values. Object initializer syntax allows for simple initialization of types without requiring an explicit constructor to be written:
public class Point
{
int x; int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
Point p = new Point { X = 0, Y = 1 };
Again, what gets compiled here is precisely what the client would write, given that there is no constructor for Point:
Point p = new Point();
p.X = 0;
p.Y = 1;
Verifying this in CIL is pretty easy:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 28 (0x1c)
.maxstack 2
.locals init (class Point V_0,
class Point V_1)
IL_0000: nop
IL_0001: nop
IL_0002: newobj instance void Point::.ctor()
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: ldc.i4.0
IL_000a: callvirt instance void Point::set_X(int32)
IL_000f: nop
IL_0010: ldloc.1
IL_0011: ldc.i4.1
IL_0012: callvirt instance void Point::set_Y(int32)
IL_0017: nop
IL_0018: ldloc.1
IL_0019: nop
IL_001a: stloc.0
IL_001b: ret
} // end of method Program::Main
The nops are interesting, but irrelevant to our discussion (they'll get optimized away by the JITter at runtime, anyway). The interesting part of this is the sequence of instructions at 0002, 000a, and 0012: newobj to create the Point instance, callvirt set_X and callvirt set_Y to set the X and Y properties, respectively. (In C#, the property construct basically maps to compiler-generated get_ and set_ calls accordingly.
And this isn't limited to primitive type fields, either; we can do the same for complex fields, as in:
public class Rectangle
{
Point p1; Point p2;
public Point UpperLeft { get { return p1; } set { p1 = value; } }
public Point LowerRight { get { return p2; } set { p2 = value; } }
}
Rectangle r = new Rectangle {
UpperLeft = new Point { X = 0, Y = 0 },
LowerRight = new Point { X = 5, Y = 5 }
};
Verifying that this is similar IL to the Point example above is left as an exercise to the reader. (Which is to say, it's there, but it's a bit long and doesn't really prove much; trust me on this.)
Note that along with object initializers, C# 3 also introduces a similar syntax for initializing arrays and collections of various forms; this is more fully documented in the C# 3.0 Language Specification that ships with the PDC Preview bits, but lexically looks pretty similar to object initializers, so I'll just refer you to that document for details.
Anonymous types
Combining the above two features brings us to an interesting conclusion: if we are teaching the compiler to infer static type information and provide some basic defaults for types, then we can actually expect some fairly interesting intuition on the part of the compiler now--in particular, the compiler is now smart enough to be able to infer an entire type during compilation. Thanks to the object-initializer syntax (to provide the necessary constructor capabilities) and the implicitly-typed local variable syntax (to be able to avoid having to name the type), we can write the following and expect a statically-typed class out of it:
var x = new { UpperLeft = new Point { X = 0, Y = 0 }, LowerRight = new Point { X = 5, Y = 5 } };
Again, thanks to the initalizer syntax, the compiler now has enough information to be able to auto-generate the following:
class __This_Name_Really_Doesnt_Matter
{
private Point _Field1;
private Point _Field2;
public Point UpperLeft { get { return _Field1; } set { _Field1 = value; } }
public Point LowerRight { get { return _Field2; } set { _Field2 = value; } }
public override bool Equals(bool rhs) { ... }
public override string ToString() { ... }
public override int HashCode() { ... }
}
which, if you think about it, is pretty cool. Project DLinq, the relational access project Microsoft introduced at PDC, will use this to address the partial query problem that plagues automated object-relational mapping layers, as now we can introduce new types into the system (as return types from an ad-hoc query) in just a line or two of code, rather than the twenty or so that would otherwise be required.
Extension methods
Another significant addition to the C# 3.0 language will be extension methods, whereby one class can lexically "inject" methods into another class by declaring a specific form of static method on a static class. Once again, however, it will be pretty clear that this is pretty much all just compiler syntactic sugar, and once again will play a significant role in DLinq.
To declare an extension method, create a static class (a new feature of C# 2.0, a static class is a class that can never be instantiated--in many respects, it is a formalization of the old procedural library concept from C or Pascal) that contains a static method as usual, but with one minor difference. To make this method an extension method, declare the first parameter to have an additional modifier, the this keyword, to indicate the type to which this method will extend.
This is a bit confusing, but bear with me--a few examples will make it clearer.
From time to time, every object programmer has lamented the inability to "slip in" functionality on a base class they do not control--one of the classes from the Framework Class Library, perhaps, or a class that comes out of a commercial third-party library to which they do not own the source. (Even open-source projects are resistant to this kind of injected change, because forking an open-source project is not a task undertaken lightly--you will have to make the same changes to every successive version of the library, an unenviable task.) Using an extension method, the compiler will effectively "pretend" that the extension method is declared on that class, and allow for invocation of the extension method as an instance method of the object.
Begin with a basic class, perhaps our Point class from before:
public class Point
{
int x, y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
As we work with the Point class, however, it becomes obvious that Point doesn't provide some form of critical functionality--perhaps it doesn't support native transation to and from XML, for example. (The fact that XMLSerializer will provide that functionality for this simple of a type is irrelevant for now; substitute your own favorite example, if you prefer.) What we'd like to do is "slip in" a pair of methods, ToXML and FromXML, that produce and take a string, respectively. Unfortunately, Point is not under our control, and although we could decompile it to C# and recompile (which won't work with strongly-named assemblies), that's obviously a hack.
Extension methods offer a way out:
namespace Extender
{
public static class XMLUtil
{
public static string ToXML(this Point pt)
{
Console.WriteLine("Imagine cool XML code here"); }
}
}
}
To "kick in" an extension method (or, perhaps more appropriately, a set of extension methods), we need only reference the namespace in which the extensions are declared with a using statement, as we would otherwise do for a normal class. This tells the compiler that the extension methods are now lexically "in" the class' interface, and are available for use. Only now we can use the ToXML method on a Point instance directly, as shown below:
Point pt = new Point { X = 0, Y = 1 };
Console.WriteLine("pt.ToXML = {0}", pt.ToXML());
A horrendous violation of encapsulation? Not particularly--notice what the C# compiler will do with this call:
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 45 (0x2d)
.maxstack 2
.locals init (class Point V_0,
class Point V_1)
IL_0000: nop
IL_0001: nop
IL_0002: newobj instance void Point::.ctor()
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: ldc.i4.0
IL_000a: callvirt instance void Point::set_X(int32)
IL_000f: nop
IL_0010: ldloc.1
IL_0011: ldc.i4.1
IL_0012: callvirt instance void Point::set_Y(int32)
IL_0017: nop
IL_0018: ldloc.1
IL_0019: nop
IL_001a: stloc.0
IL_001b: ldstr "p.ToXML() = {0}"
IL_0020: ldloc.0
IL_0021: call string Extender.XMLUtil::ToXML(class Point)
IL_0026: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_002b: nop
IL_002c: ret
} // end of method Program::Main
The giveaway is at instruction 0021: the C# compiler is actually generating a standard static method call on Extender::XMLUtil::ToXML, passing in the Point instance in question (which is why the first parameter being decorated with "this" makes sense, since it's conceptually the "this" reference normally implicit in an instance method) for manipulation and examination by the extension method. No violation of encapsulation whatsoever. In fact, the extension method has zero access to non-public members of Point, thus avoiding one of the principal concerns over aspects voiced by critics of AOP, that of managing state in aspects and/or across classes and aspects. But for all other purposes, this is aspect-oriented programming in the grand tradition of AspectJ, just with a very limited pointcut capability. (It would be trivial to write the corresponding AspectJ aspect to my ToXML method above, but I'll leave that for Ron Bodkin, Nick Liesecki or Ramnivas Laddad--or anyone else passingly familiar with AspectJ--to contribute on their own blogs. )
Note that of course extension methods introduce some interesting method-overload-resolution rules, such as when the extension method clashes with a method on the extended type (the extended type wins) or when two extension methods of the same name and signature are both brought in via a using clause (in which case the "most nested" using expression, inside namespace declarations, wins). These rules are likely to change as feedback filters in on the released PDC bits, so if you're to bet the farm on this particular aspect of the language (pun intended), make sure to keep up with the latest C# 3.0 specification changes as well.
Note also that as of this writing, the PDC Preview bits also come with this note in the documentation:
Extension methods are less discoverable and more limited in functionality than instance methods. For those reasons, it is recommended that extension methods be used sparingly and only in situations where instance methods are not feasible or possible. ... Extension members of other kinds, such as properties, events, and operators, are being considered but are currently not supported.
If you are a C# programmer and particularly desire those styles of operations, now's the time to let Microsoft know.
Lambda Expressions
The lambda expression, long a favorite of Lisp programmers, has come to C#. While the .NET platform has always had the capability to create delegates, which are essentially managed function pointers, and while delegates could always be used as a poor man's subsitute for lambda expressions, former Lisp programmers have always had a yearning in their heart to see real lamba expressions in their favorite .NET language. Anders heard the call, and answered: where C# 2.0 introduced the ability to create anonymous delegates, method bodies that are implicitly converted into a class with a single method (the anonymous method itself), C# 3.0 introduces lambda expressions, the ability to define a method body--or, more accurately, just a block of code--in a fairly terse and elegant way. The lamba expressions are probably the hardest part of the C# 3.0 specification to grok if you've not nseen it before, however, so be prepared to spend a little time with it before it all makes intuitive sense.
In essence, a lambda expression follows the pattern aid down by a delegate, so to begin we start by declaring a delegate type to which lamba expressions should be assigned; in the PDC preview documentation, for example, they use this example:
delegate R Func<A, R>(A arg);
For those of you unfamiliar with delegates and generics syntax in use here, we are declaring a generic delegate type that, when constructed, will expect a single argument (the generic argument A) and return a value (the generic argument R). Thus, if we wanted to create an instance of Func around a method that takes an int and returns an int, the delegate instantiation syntax would normally look like:
Func<int, int> f1 = new Func<int, int>(MyClass.MyMethodTakingAnIntAndReturningAnInt);
But in the scenario where that method is a one-off, it's somewhat wasteful to have to write a complete method body inside of a class just for this. For example, if MyMethodTakingAnIntAndReturningAnInt is just multiplying the parameter by itself (a squaring function, in short), then it's a real waste of at least three or four lines of code to write it out as a formal, named method. This was where anonymous methods kicked in, so we could write it as:
Func<int, int> f1 = delegate(int i) { return i * i; };
But many feel that even this syntax is too unintuitive for casual use, so instead, in C# 3.0, a lambda expression can be used:
Func<int, int> f1 = x => x + 1;
And, as with all delegates, once constructed, any of the three versions can be invoked using the same syntax:
Console.WriteLine(f1(12)); // prints 144
So, in essence, the lamba expression is an easier way to write a delegate. Or, perhaps more correctly, to write an expression body. The C# Preview docs describe lambdas as "a functional superset of anonymous methods, providing the following additional functionality:
- "Lambda expressions permit parameter types to be omitted and inferred whereas anonymous methods require parameter types to be explicitly stated.
- "The body of a lambda expression can be an expression or a statement block whereas the body of an anonymous method can only be a statement block.
- "Lambda expressions passed as arguments participate in type argument inference and in method overload resolution.
- "Lambda expressions with an expression body can be converted to expression trees."
But goes on to note that as of the PDC Preview, lamba expressions with a statement block body are not yet supported. (Hey, it's not even an alpha yet, you have to expect a few of those kinds of wrinkles.) For right now, if you want statement block body lamba expressions, the anonymous method delegate syntax has to be used.
The last of the new features of C# 3, the query language features, isn't really a language feature per se, but a close integration of the compiler and expected library support it's compiling against, and as such doesn't really openly qualify as "language innovation", in my opinion. That said, though, it's damn useful, and what's more interesting, Java actually has a tool that can provide this kind of capability already--the OpenJava compiler tool (from the same folks that brought you Javassist, the bytecode manipulation tool that is at the heart of JBoss, among other open-source projects), which allows you full metaobject protocol capabilities, including the ability to add new keywords to the language.
And that's ultimately my point here: as you've seen, nothing that C# 3.0 introduces is really all that revolutionary once we get past the compiler--even the extension methods and lambda expressions are defined in terms of what's already present within the language and framework, making the entire exercise one in compiler syntactic sugar. Very sweet, very addictive sugar, perhaps, but just syntactic sugar nonetheless. And yet, because these features are still built in terms of the CLR, it means that we have full fidelity static-typing, even through the syntactic sugar (unlike what happens in the case of Java generics).
For ten years, Sun has insisted that Java Language and Java Virtual Machine must remain in lockstep, and as a result the language innovation in Java has either completely stagnated (the only real language innovation in Java 5 was the custom annotations model, and that was almost a direct copy of what .NET had done before), or else occurred outside of Sun's--and therefore "official Java"'s--boundaries. Sun needs to realize that the strength of the JVM by far exceeds the limited language potential of the Java language, and if they don't want to watch Java's popularity begin a steady decline, they need to cut the umbilical and let the JVM run free and the language innovation truly begin. Otherwise, it's looking like a very CLR world ahead of us.
Java/J2EE | .NET | C++
Wednesday, September 21, 2005 6:33:38 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Saturday, September 17, 2005
|
Build the JDK (on your Windows box)
|
|
Now, I own a Windows box (which runs VMWare, which runs three other Windows images and a Linux image, so perhaps it is fairer to say that I own lots of different virtual boxes but I still feel most at home in Windows), and I've tried to get the JDK (since version 1.3? 1.4? when they first introduced the SCSL licensed-source) to build under Windows on my own. Oh, I've managed to get pieces of it to build--most notably the VM--but I want the whole thing, lock-stock-and-barrel, so I can start doing some major spelunking across the entire JVM-and-related-libraries, and maybe even do a book on it.
Enter this page. I haven't tried it yet, but wow, talk about step-by-step. Have to give that a spin, maybe on a fresh VMWare image (just to avoid cluttering up the others).
C++ | Java/J2EE
Saturday, September 17, 2005 2:51:19 AM (Pacific Daylight Time, UTC-07:00)
|
|
|
No, John, software really *does* evolve
|
|
John Haren, of CodeSnipers.com, recently blogged about something I feel pretty strongly about:
There's a common trope in CS education that goes something like this: "All software evolves, so be prepared for it."
Far be it from me to imply that one shouldn't be able to respond to change; that's not my intention. But the idea expressed above contains a flaw: software does not evolve.
Duh, John… everyone knows that software changes. Features creep. Scope broadens. New platforms and whizbangs are targeted. Get with it!
I concede the obvious: of course software changes. But repeat after me: software does not evolve. Because change != evolution.
Evolution is a blind, natural process; the result of random mutations in an organism. Now it may just so happen that the result of the mutation is beneficial to the reproductive success of the organism, meaning we’d expect to see creatures with such a trait outperform others without it. That's how traits are selected for. In the overwhelming majority of cases, mutations are detrimental, and they don't stick around for long (since there are many, many more ways of being dead than alive).
Now in order to say that software evolves, you'd have to accept that your development process goes something like this: Developer opens a file at random, positions the cursor at random, punches a few keys at random. Developer then recompiles and sees what happens, hoping for the staggering luck that the resulting change actually does improve the software, and everybody loves it, so they buy it, and you'd expect to see more of it.
Okay, insert joke here about how your development process seems that way from time to time.
Jocularity aside, there's more at issue here than a flawed analogy. Of more significance is the type of thinking it can engender. Nothing "just happens" in software. Whatever it is, somebody made it happen. Someone decided. They may very well have decided in error, but they decided. They decided "well, let's just try and fit that feature in; it shouldn't cause too many problems if it goes out only 70% tested... if it breaks, we'll deal with it then." Or they think "yeah, a talking paperclip… why not?" In other words, magical thinking. Don’t do that.
And CS departments should stop teaching that. Let them stress peopleware instead.
His presumption here, which may seem fair at first, is that all evolution is basically random. And, frankly, that's not entirely without truth. But what he sees as the randomness in the system is different from the randomness that I see, and that's that the users are what bring the randomness into the system.
Look, how many times hasn't a user told you, "We need this feature", only to discover six months after shipping that feature that nobody's really used it, but that it in turn sort of answered a different problem that you ended up providing for them as a new feature? See, the software itself doesn't evolve randomly, but the users' interactions with the software do. That's evolution, that's healthy, and that's how software evolves.
In short, it's recognizing that the users are part of the system, too, part of the organism that makes up this bizaare and wonderful world we live in, and their input is often exactly that: random. Which is probably why it's so important to have the on-site customer, as per agile development's recommendation, because you never know when randomness will strike and make your life better/faster/easier.
|
 Thursday, September 15, 2005
 Wednesday, September 14, 2005
|
Book Review: Rootkits, by Hoglund/Butler
|
|
The title is a bit scary, but "Rootkits", by Hoglund and Butler, really is anything but. Oh, I'll admit, their talk of how rootkits--programs that hackers install onto your system that patch into kernel space and thus are undetectable by any user-mode program--is scary, but then they walk you through the process of developing your own rootkit, thereby giving you some awareness of what a rootkit looks like, acts like, and therefore can be discovered and killed.
Well, in theory, anyway.
To put it bluntly, I'm loving this book, if only because it's the first book I've run into that really sits down and explains how to write a device driver, not to mention how to communicate with it from user mode. I've been fascinated with that very idea for many years now, but all the DDK-based material I've found--books, articles, etc--all assumed that you wanted to write some variation on the SCSI driver or something, implying that you care more about device-level details than you do in writing kernel-mode code. Rootkits, of course, are nothing like real device drivers, but a lot more like what I'm interested in exploring and displaying (that is, getting at program information from within the kernel--very useful for debugging scenarios, for example).
By page 30, you've already written and compiled a basic kernel driver, and by page 39 they've discussed how you can have your driver expose itself as a special file handle for communication with user-mode code. Pages 40-43 talk about loading the driver from code, and 43-46, how to extract your driver from a user-mode program as a resource, suitable for loading (because, of course, rootkits need to piggyback on top of other code to install themselves, stealthy-like). Pages 46-47 talk about how to make your rootkit survive reboot, and that concludes Chapter Two.
Wow. I'm in love.
It's not the be-all-end-all book on drivers, nor is it going to necessarily turn you into a l33t hax0r, but if you ever wanted to get started understanding how rootkits work (so as to start looking for them on your own system in order to remove them) or just use that knowledge for more benign purposes (such as trying to figure out NT internals so you can more efficiently--and automatedly--debug services or server-style programs), this book rocks. Easily a classic, and one I'm probably going to carry around with me as much as I do Hoglund's other book (with Gary McGraw, one of my favorite security authors), "Exploiting Software".
|
|
JavaZone 2005... or, an excuse to write about Oslo
|
|
I'm in Oslo, Norway, for the next four days, ostensibly to speak
at the JavaZone 2005 conference, but the truth is, I don't really care why I'm here.
Truth is, I've discovered that Oslo is quite possibly the closest place
on the planet to claim being a real-life Norman Rockwell scene.
The drive from the Oslo airport to downtown Oslo (to the Radisson SAS
hotel) is quite possibly one of the most beautiful drives I've ever had
the pleasure of making--it really is like driving through a Norman
Rockwell painting, with the farm fields off to both sides, thick lush
forests rising on the hills, and the buildings just barely visible,
nestled in amongst the trees and rising slopes. If it weren't for the
fact that I know this place is going to be just buried in snow in the next month or two, I'd seriously consider living here for a while.
Oh, and I've also discovered that Norway is one of the western European
nations that doesn't (yet?) take the Euro--tip to American travelers, don't take cash out at the Amsterdam airport when you're headed off to a non-Euro country. It's an expensive mistake. 
Conferences
Wednesday, September 14, 2005 3:29:45 AM (Pacific Daylight Time, UTC-07:00)
|
|
|
C-omega's Revenge: Project LINQ
|
|
For anybody who's not been paying attention to the technical news
front, this week is Microsoft's PDC in LA, and one of the things
they've announced for the next release of Visual Studio is Project
LINQ, short for Language INtegrated Query. In essence, C# 3 and VB 9
are going to integrate (through a variety of language extensions, such
as lambda expressions) query capabilities directly into the language,
making much of the need for an automatted O/R mapping layer (such as
Hibernate or JDO) a thing of the past (at least, in theory).
If you haven't had a look, check out Dion's or Ben's
weblogs for details; there's also a paper coming out (by Don Box and
Anders Hjalsberg) with the LINQ Preview bits that contains the best
description of the language/tools I've seen thus far.
|
 Tuesday, September 06, 2005
|
Ben learns the difference between "characters" and "bytes" the hard way
|
|
Ben Galbraith discovers a little snippet about XML encoding that is both subtle and evil:
A while back, I was working on a system feature that read in some XML from the filesystem, XSLT'd it into HTML, and served it up to a browser. The XML had a bunch of characters from the higher Unicode ranges (i.e., >255), and wouldn't you know, when viewed in a browser, these characters showed up as garbled data. Not "The Box"–that ugly little placeholder used when a font doesn't contain a character for a given code point–but usually one to three seemingly random characters that had nothing to do with the character that was supposed to be displayed.
...
And then, whilst reading through some of the backend code, I saw this innocuous little line:
Document document = new SAXBuilder().build(new FileReader(file));
See the problem? Look again. ... This is the code I should have written:
Document document = new SAXBuilder().build(new FileInputStream(file));
If you hand an XML parser bytes, which is the currency of InputStreams, the parser handles converting those bytes to characters itself, and uses the encoding in the XML prolog to configure itself for that process. If you hand it characters... it's stuck using those characters and can't affect the decoding process one whit, since it occurs a level beneath it. By the way, anybody working with Streams in .NET had best be aware of the same basic problem....
The lesson? Be aware of your encodings, at all levels of the translation and processing machine... And if you don't know the difference between UTF-8, Unicode and ASCII, you're falling to the trap that goes by the name of Leaky Abstractions....
|
 Sunday, September 04, 2005
|
Installing Vista B1
|
|
So I've finally unpacked my office enough to find my game machine... er, workstation, that is... which has as its main benefit a removable drive tray that contains the drive I boot from. Advantage being, when I want to try out new stuff (such as Windows Vista) on a raw hardware machine, I don't have to screw with partitions, nor do I have to be worried about trying to make it work inside a VMWare or VPC image. So, dusting off the removable drive tray that contained the PDC build of Longhorn, I stuck it into the drive tray and prepared to install (by blowing away the Longhorn partition already there) Vista Beta 1.
For starters, it's nice that it boots into a graphical mode right away (though I'm sure the 2-tone black-and-white "Longhorn" boot animation-and-image isn't going to remain as such, because it looks really ugly), and then only asks for which partition to install on (choice of two in my case, the boot drive or a data drive inside the box) and a machine name, before it gets to the "I'm going to chug away for Lord knows how long" screen indicating that it's installing stuff. This is kinda nice, particularly for so-called "power users" like my father, who has more of a tendency to get himself into trouble with options than is really served by having them. (He'll moan and gripe, I'm sure, but frankly, if it means less tech support calls to his son, then that is a Good Thing.)
Of course, installation took forever (I didn't bother timing it--I didn't have a calendar handy), but it's been a pretty well-understood truism about installing software for a few years now, that when you get to that "Please wait" screen, you go off and do something else. (In my case, it was running network cords behind the office furniture and putting my kids to bed, including chastising the elder son for playing with my Magic cards without my permission.) One thing I would like, however, is that the green progress bar at the bottom of the screen actually monitor progress of the complete installation process, not whatever step it happens to be executing--it keeps crawling across to the right, then resetting and starting over. Kinda like the bullies used to do on the playground--snatch your lunch money, then hold it up over your head, "C'mon, reach for it, reach for it, HUP!" and yank it up out of your reach when you do jump. (Not that I'm bitter about the experience or anything....)
When installation finally completed and the box rebooted, it goes through an interesting set of personalization settings application--not sure what they were all for, but I guess that will become more apparent over time. Immediately on bringing up the user shell, though, the Vista beta tries to load XP drivers that aren't natively supported inside Vista, which is kind of a nice touch, because I could tell this would be rough if I had to go back to 640x480; at least I think it was 640x480, because it felt like 200x150. It found my graphics card (a GeForce something-or-other, I forget) and installed those drivers, though it still booted into Really Hideous Fat Pixel Mode on startup. That said, though, a quick right-mouse-click on the desktop and changing-of-settings brought it into a more reasonable 1280x1024 mode pretty snappily. It still didn't recognize my sound card, however.
That's about as far as I've gotten with it thus far, although I noticed fairly quickly that Microsoft still hasn't fixed that critical bug that's been in Windows since the 3.0 days... you know, the one where they don't let you cheat at Solitiare...?
Windows
Sunday, September 04, 2005 11:42:47 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Saturday, September 03, 2005
|
Of blogging, reviewing, endorsing, opportunity cost, and ethics
|
|
Scott Hanselman recently announced that he was doing to do a review of a product on his weblog, which isn't unusual; what is, for him, was that he was being paid to do the review, and a couple of readers of his weblog took issue with the fact that Scott was violating his own ethical blogging policies to do so. To wit:
Er.. that's not a review, that's dangerously close to payola.
and
Yeah, but in an earlier post you said you'd only post about software you felt passionate enough to post about.*
Sho' nuff. That's the essence of a blog; it's why they work.
I could maybe understand if they provided you a free copy of the software to review at your discretion, but directly _paying_ for a review is kinda strange IMO. It's definitely not wrong, and you had a nice disclaimer in there and all. But it ultimately undercuts the whole passion argument. "I'll only write about products that I think kick ass.. oh yeah, and products that someone pays me to write about."
I'll say the same thing to you that I say to my wife: I still love you, just a tiny bit less than I did yesterday. ;)
* as I recall, you made a big deal out of this specific point.
Scott later felt guilted enough into refusing payment for the review.
Frankly, I think Scott caved, and there was no reason for him to do so. Here's why:
- Scott's ethics and sense of ethical responsibility are so far above reproach, it's hard to believe we're having this conversation about him.
- There is a crucial difference between "reviewing", "endorsing" and "sponsoring", as I see it (though all of these terms are weaselly enough that we could easily spend a lot of time just in definitions and semantics). A "review" implies that the individual in question (Scott) will offer up a candid, no-holds-barred discussion of the product/tool/technology/whatever, with no implicit bias and no implicit agenda in performing the review. An "endorsement" means the individual has evaluated the product, and thinks that people should be using it if they're not already. Neither of these thus far implies payment for review or endorsement--for example, I endorse Java, and I endorse .NET. In fact, I endorse a whole bunch of books, too.
- That said, however, my time (as is Scott's) is a precious resource--I don't have a lot of it to give away. If a company wants me to do a review of their product, particularly if it's something I'm not going to pick up as part of my normal activities, then I want to justify the time--the time I spend working on the review is time I'm not spending on other paying work or writing. The economists call this "opportunity cost": what are you giving up in order to pursue a particular activity? In Scott's case, like mine, it's either paying work or else it's personal time with the family, neither of which I'm gong to sell cheaply.
For a company to pay me to do a review of a product is not unethical. For me to post that review of the product on my blog is not unethical (though a bit odd; quite frankly, I would think the company would want to look at it first, and if it's a positive one, I would think they'd want to post it on their site, not my blog).
Where I think Jeff Atwood (the commenter on Scott's blog) is concerned is that it's hard to tell if Scott's review was positive because of the fact he was being paid for the review, and there we have the crucial question, that of motivation. What was Scott's motiviation while he was writing the review? This is a question that only Scott can answer (and frankly, I think he did a damn good job of answering it when he turned down the fee), but for readers of Scott's weblog, the crucial question has to be, "Do you trust Scott to offer up a fair review even if he's getting paid for it?" For my money, I think yes, because Scott's one of those people who can only be described as "brutally honest". The idea that Scott would change what he says just because he's getting paid to review something just doesn't jibe with what I know of the guy.
Meanwhile, moral support for Scott has emerged, in the form of endorsements (yes, I use that word deliberately) of his character from Carl Franklin and Greg Hughes, and Mike Gunderloy points out that
The software review business is an ethical muddle - much more so on the printed magazine and major site level than in blogdom. Many people aren't aware of it, but print magazines generally approach software vendors with a pitch similar to this: "We'd like to review your product X in our upcoming issue. You'll need to send us a copy with a full license for our reviewer. We're sorry, but this has to be a full license, not a Not-For-Resale license. That's our firm editorial policy." The reason for this policy? Because the pay for writers for writing reviews stinks, and reselling products on eBay after the review is written is a nice little bit of extra income.
Pretty much everyone, big or little, accepts free licenses - sometimes full, sometimes NFR - of the product under review. I do it myself (and disclose it on my site). So you always have to take that into account; the reviewer didn't pay the $10,000 for that fancy product that he's raving about. Possibly his opinion would be different if the money were coming out of his own pocket.
All that said, I'm glad to see that Scott isn't taking money directly from product vendors. That crosses a traditional journalistic ethical line, and I'm enough of a traditional journalist to not want to cross that line.
I'll admit, I'd never engineered a license-for-resale deal just so I could turn it around on eBay (and, frankly, doing so with an Not-For-Resale copy is actually bluntly illegal) while I was editor at TheServerSide.NET, but I have frequently approached companies about receiving a free NFR license in order to evaluate their product and, if I like it, implicitly or explicitly endorsing it during presentations and classes. Fact is, that's a large part of what people pay me for: to help them navigate the muddy waters of the thousands of different products, tools, libraries, and/or technologies out there, and it's in a company's best interests for me to have their product handy when I'm asked a question in that space. (Speaking of which, I'm always amazed when companies don't pursue this in an aggressive manner--you don't believe in your product enough to give out free copies to influentials within the industry? Then get out of the business, because you're just going through the motions and will have your shorts handed to you by a company that does.) Does that make me unethical? Absolutely not--I'm pursuing exactly the avenues that people pay me for, to spend the time researching and investigating, so they don't have to.
I won't say that I've never written about a tool or technology that I didn't believe in--fact is, there were some slow months in the past couple of years, and I, like the proverbial young starlet, had to do some pieces that I hope don't come to light someday. That said, though, all of those pieces (and there were thankfully very few of them) I refused to sign my name to. Because, in the end, that's what Scott--and I--really sell. My name, Scott's name, there's an implicit trust from the people who respect us, that we won't attach our name to something cheaply. And folks, I can guarantee two things: I won't, and neither will Scott. And in the end, you either trust our word on that, or you probably don't care about our names to begin with. 
Saturday, September 03, 2005 9:29:45 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Thursday, September 01, 2005
|
It's time to do away with this "Web" service thing... long live XML services!
|
|
Stefan Tilkov blogs about my rebuttal to ERH's rather limited comment about "nobody's doing Web services over anything over HTTP anyway" (which generated some additional postings, most notably from Steve Vinoski), but says something pretty fundamental:
I think its just a matter of perspective: for Web scenarios, nobody uses anything but HTTP anyway, and for the vast majority of company-internal use-cases, Id consider HTTP to be a much better solution than some vendors proprietary messaging middleware. But even if one assumes that HTTP is going to become the protocol of choice for EAI as well, WS-A still has merit to support asynchronous processing of SOAP messages. Forgetting for a moment the word "proprietary" here (because the difference between "proprietary" and "open standard" is much smaller than most people think), it bears repeating that not all of the work in this space is happening over the web; in fact, I'm finding that more companies are interested in integrating inside the corporate network than they are over the Internet. Granted, the B-to-B scenario is still compelling and attractive, but most corporations seem to be more focused on getting their internal house in shape before they start inviting guests over.
The problem is that when we say "Web services", the "web" part of it implies HTTP and REST and all that other stuff. It's time we faced reality: SOAP is not just for doing stuff over the Internet. It's time we started calling them what they are: XML services. Unfortunately, I don't think the W3C is going to change the name of WSDL to XSDL or XS-Addressing any time soon, but that doesn't stop us from at least trying. My promise: if you catch me, in a presentation or class lecture, using the term "Web services", and you're the first to point it out, I owe you a quarter. Long live XML services!
|
 Monday, August 29, 2005
|
C#: Is the Party Over? Not to anybody with 20/20 eyesight...
|
|
After a circuitous route through Davis before it got here to Seattle, my copy of Java Developer's Journal finally showed up at my doorstep over the weekend, and from the top of the magazine's cover blared Calvin Austin's editorial entitled "C#: Is the Party Over?"
Huh?
As I read through the editorial, I began to realize that not only were the points ill-conceived, but that Mr. Austin doesn't even offer up credible or factual basis for his perspective--in other words, this is FUD at its best, the very same tactics that Sun accuses Microsoft of using when the facts don't suit.
Mr. Austin begins by justifying his expertise on the subject by saying,
One of my tasks at Sun was to keep abreast of the technologies in the marketplace that competed with Java. Somehow, we're to believe that since his job was to "keep abreast" of all competitors to Java, that somehow Mr. Austin is now a C# expert. Which I find an interesting position to take--does that mean that the various marketing and project managers at Microsoft, whose job it is to keep abreast of all .NET competitors, are now Java experts? If so, then we have to take as equally credible their claims that the number of .NET developers exceeded the number of Java developers in .NET's first or second year of release, and we have to take as equally credible their claims that .NET has now surpassed Java/J2EE in corporate environments for enterprise development. Frankly, I find both sets of claims equally absurd.
Next, he begins his arguments as to C#'s iminent demise:
The .NET platform has been under constant development, often too fast for many corporate users to accept. There has been a 1.0, 1.1 and 2.0, each which could be counted as a significant version in their own right. Huh? First of all, the 2.0 release hasn't shipped yet, but we'll mark that as a nit--it ships on Nov 7th, so we'll just presume that Mr. Austin didn't hear that bit of news and believed Microsoft's earlier estimates of a ship date in August or September. (Then, if he were writing this article a few months ahead of time, as is pretty common with print magazines, he would have been correct had Microsoft shipped on time. Which I find amusing--that, if you take my explanation as germane, he believed Microsoft's ship date estimates when nobody else did.) But to claim that 1.1 was a "significant version" over 1.0 is absolutely ludicrous--as the guy who was responsible for the reference section of C# In a Nutshell, I can attest for a fact that the Base Class Library did not change more than a fraction of a percentage of the total surface area--I know this because I had to update all the method signatures and types that changes between 1.1 and 1.0. Given no language changes, no library changes, and no major enhancements to Visual Studio (which doesn't really count as part of C#, IMHO, but we'll include it since the two are pretty inseparable), I fail to see how 1.1 can be any different than 1.0. Which reminds me, didn't Sun release JDK 1.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7, and 1.2 all within a five year period (1995 - 2000)? That's three major releases, not counting the "point releases", not to mention a complete marketing rebrand, all within a five year period of time.
What I find fascinating, however, is the implicit criticism that innovation and progress is bad. Corporate users aren't accepting of too many changes, true--this is precisely the experience Sun faced during the 1.1.x hyper-release cycles, when they were castrated in the press for doing too many releases in too short a period of time. But an eighteen-month release cycle (which is the current development cycle for the .NET teams) is hardly what you call rapid, and frankly, I've heard a number of developers complain that the releases are too far apart to begin with. Coupled with the fact that both platforms support a very good side-by-side deployment story, I think both Sun and Microsoft could stand to shorten their cycles, not point-and-kvetch that the other side is releasing too quickly.
Next we see Mr. Austin point out that C# hasn't been the astounding success Microsoft wanted it to be:
Looking at the forums, Visual C++ and Visual Basic and not C# attract the lion's share of the forum attention. ... which, it could be argued, is because those two languages underwent major revisions in adapting to the CLR platform...
In addition, the underground community site, gotdotnet.org, has undergone significant site and management changes. Underground? Like GotDotNet is some kind of rave that if only the cops knew about, they'd bust up? That GDN hasn't been the stellar success its founders hoped it would be is pretty obvious, but there's some very smart people working on GDN (including a well-known former ThoughtWorks consultant) to fix that. But what, exactly, does GDN have to do with C# and its adoption curve?
The C#, C++ and C compilers are now free, although not obviously as optimized as the professional edition. Source? Factual basis for this statement? From what I can tell, looking at the binaries and implementation, the C# compiler that comes with the freely-available .NET Platform SDK is exactly the same beast that ships with the Visual Studio development environment.
Mr. Austin continues with his analysis by pointing out that C# "didn't make the grade" because:
... the Java platform did not stand still. Many of the benefits that the Java platform delivered were not solved by moving to C#, the most significant difference being OS independence. Which was never a goal of the .NET platform in the first place. Microsoft admits as much. They're happy to leave the OS-independent world to Java, because their market research indicates nobody really cares about that. *shrug* Agree or disagree, that's their position. Given the number of people who standardize on Windows desktops and servers, it hardly seems necessary to point out that supporting only the Windows platform is still a fiscally-viable decision to make.
While C# was in rapid release mode, the Java platform was able to fine-tune the language and at the same time invest heavily in stability and scalability. "fine-tune the language", by adding more language features and functionality than ever before? That's like suggesting that the Titanic's brush with the iceberg was a "slight change of direction". While I like most of the features introduced in Java5, one can hardly call it a "fine-tuning", particularly when it's fairly self-evident that many of those features were driven by similar features being released in C#. Why else, for example, did Java finally decide to get an enumerated type?
Deploying a .NET service leaves a company a small choice of application servers and OS versions. Well, he got that one right, anyway--it's called Windows. Assuming you don't count Mono (which apparently he doesn't, as evidenced by later prose), which runs on Solaris, Linux, AIX, and a bunch of other *nixes, basically all the same OS'es that Java runs on.
The criticism continues with his prouncement that "open source changes everything":
While developers had to get budget approval for MSDN licenses, the Java colleagues were able to deploy a system for free. Hmmm. If I go to the Framework SDK site, I find that I can download the core SDK--command-line compilers, including ASP.NET, ASMX, WebForms, the complete stack--for free. Granted, Visual Studio isn't free, but neither is IntelliJ IDEA. If you want an open-source .NET IDE, consider SharpDevelop. If I purchase Windows Server 2003, the .NET SDK is already preinstalled, with rights and license to deploy .NET code on that server. 'Splain to me how I need an MSDN license for this, again?
The growth of open source Java hasn't stopped there. You only have to look at Hibernate, the Spring Framework, and Struts/Shale to see that developers can work together to solve their own problems. Yes, and NHibernate and Spring.NET are, of course, completely not worth considering as either "open source" or ".NET" enough to merit mentioning, right? And Struts--that's that framework whose central developer abandoned and moved to embrace Java Server Faces, right? Leaving all those people who spent time and energy learning and deploying Struts to wonder if their investment was about to be cancelled? Fact is, Mr. Austin, if you were as "hip" to the .NET space as you claimed to be, you'd know that the open-source movement is encroaching into the .NET space just as it is the Java space, and that open-source .NET projects are just as useful and powerful as open-source Java projects.
And no Java-centric criticism of .NET is complete without bashing Mono for a bit:
Mono today is still a development project much as .NET is still looking for full traction. I think I'll let Miguel answer that one: I know he (and Novell) disagree with that assessment. But that's his fight to fight, as far as I'm concerned. I just find it ironic that Sun bashes .NET for being platform-specific, then pooh-poohs the platform-independent version of .NET that's open-source to boot.
Mr. Austin wraps up his editorial with:
Is the C# party over? If the plan of C# was the slow the defection of Visual C++ developers to Java, then it was certainly better than nothing. The long-term savings for Microsoft in sharing a CLR between projects was more than worth the initial effort. However, C# is still not the de facto choice for web site or enterprise development and other languages such as Python and PHP, which are bringing in a new generation of developers who don't have a need to migrate Visual C++ applications. C# isn't going anywhere soon but its best days may be behind it. Wow. So much wrapped up in so few sentences. Let's take this one slowly.
- Is the C# party over? Considering how he's been equating C# and .NET as one and the same thing, Mr. Austin clearly demonstrates his inability to tell the difference between languages and platforms, a failing of Sun's for the past decade. Even assuming C# as a language were to fall apart tomorrow (highly unlikely), the other languages--Visual C++, Visual Basic--would keep .NET alive for a very long time to come. So, if you're to refute my arguments, make sure you clearly delineate between refuting the language (C#) or the platform (.NET). Combine this with the fact that Microsoft is about to unveil the plans for C# version 3.0, it hardly seems logical to suggest C#'s party is over.
- If the plan of C# was to slow the defection of Visual C++ developers to Java... An interesting insight, one that I particularly agree with. But it also sells short the idea that Microsoft simply saw the union of Java-the-language and the platform (COM at the time) as a Good Thing, one that they wanted to enhance and adopt for themselves.
- ... then it was certainly better than nothing. Ah, a masterful choice of words, implying that there were much better things they could do, but chose not to for a variety of reasons. What those things were, who knows, particularly since Microsoft DID try to use Java as the core of their platform going forward (by leveraging Java and custom attributes, yielding J++) but were sued out of it by Sun.
- The long-term savings for Microsoft in sharing a CLR between projects was more than worth the initial effort. Don't be too quick to toss this off, Mr. Austin--the costs in sharing a platform between languages are subtle and deep. The cross-language .NET project is a lot more complicated than many people believe, and we can see that trying to build a platform that's somehow "universally acceptable" to all kinds of languages is a difficult thing by looking at the efforts under way on the Parrot project. Microsoft has certainly done a powerful thing in building the CLR--and standardizing it--but it wasn't easy, and something whose costs and effort hasn't been fully measured yet.
- However, C# is still not the de facto choice for web site or enterprise development... Not amongst the Java crowd, certainly, but there's a lot of sites out there with ".aspx" in their URLs--measure for yourself if you don't want to believe somebody else's statistics--seemingly putting the lie to Mr. Austin's cavalier statement.
- ... and other languages such as Python and PHP, which are bringing in a new generation of developers who don't have a need to migrate Visual C++ applications. Huh? This part of the sentence doesn't even make grammatical sense, but what I think he's saying is that a whole collection of website developers, who currently use Python and PHP, have no need or desire to adopt C#. Got news for ya, Mr. Austin, this is the same crowd that has no need for Java and J2EE either. They're hung up on Ruby and Rails right now, and probably still have a huge collection of Perl scripts that they use on a regular basis that have no easily-ported Java--or C#--equivalent. Fact is, the scripting crowd has very little use for any statically-typed, compiled language, be it C++, Java, or C#. Or VB, for that matter.
In the end, the reason I refute the meat of Mr. Austin's editorial is simple: Java developers are being fed a constant stream of FUD about the .NET platform these days, just as the .NET community is being fed its own set of FUD about the Java platform by various players there, too. I find myself spending about equal amounts of time explaining the Java community to the .NET world as I do explaining the .NET world to the Java community, and although I typically get nothing but ridicule, anger and/or disbelief from the various zealots on both sides, I find that the majority of developers I speak with on the subject are quite interested to hear what the "other side" is doing. It goes back to what I said earlier--the more you know about the other platform, the more you can leverage their experiences and innovations for your own use. But the first step to learning about the other platform is to recognize that they're doing something useful, and not just write off everything happening as irrelevant or meaningless, or to make such boldly unsustainable claims as "The Party's Over" or that "its best days are behind it". More importantly, it's editorially irresponsible that JDJ published this tripe; granted, JDJ's readership may think it wants to hear that the .NET platform isn't useful and powerful, but that's a factually incorrect statement and is likely to cause more pain in the long run than to simply face up to the fact that .NET is Java's twin brother and can do anything Java can do.
.NET | Java/J2EE
Monday, August 29, 2005 5:31:17 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Sunday, August 28, 2005
|
Best practices, redux
|
|
Jared Richardson took issue with my assertion that there's no such thing as best practices, stating that, in essence, it's not kosher for me to deny existence of something that I have to define:
They said "There are no best practices" and then they had to define the term... but they defined it wrong! A best practice isn't a required practice or a universally dominant practice. It's just one of the best ones. It's used quite often, but not everywhere and not always. (No such thing as best practices? Sure there are!)
Unfortunately, Jared, the semantics of the term "best practice" implies exactly that: something that's used everywhere and always, for when would anyone choose not to use a "best practice"? And if it's not used everywhere and always, then it's not "best", implying "better than all alternatives", ya?
How about, at the end of the day, we just drop the term "best practice" altogether, and stick with "useful practice" instead? Would that satisfy everyone's sensibilities?
|
 Friday, August 26, 2005
|
Conference tour: Q4 2005
|
|
A couple of people have asked me what my speaking schedule looks like for the next quarter, so, barring any last-minute cancellations or shifts in schedule, here's where I'm going to be over the next few months:
- Aug 27-28, Cincinnati, Ohio: Southern Ohio Software Symposium, doing my usual raft of $NFJS talks: "The Ten Fallacies of Enterprise Computing", "Effective Enterprise Java: Security", "Introduction to Web Services, 2005 edition", "Java Metadata", and an architecture/end-of-conference open forum
- Aug 31, Portland, Oregon: Portland Area DotNet User Group, doing a talk on .NET persistence options
- Sept 14-15, Oslo, Norway: JavaZone, doing talks on "Concrete Services" and "Effective Enterprise Java"
- Sept 16-18, Chicago, Illinois: Great Lakes Software Symposium, another $NFJS show
- Sept 20, South Bend, Indiana: Michiana Area DotNet User Group, doing "Intro to WS-2005"
- Sept 25-30, Arhus, Denmark: JAOO, doing "Passing Messages", "Core Indigo Patterns", "Effective Enterprise Java" and "C# Intro" (for Java developers who haven't picked up the CLR/.NET thing yet)
- Sept 26-29, Boston, Massachusetts: SD Best Practices (yes, I know this overlaps with JAOO; it's going to be a very interesting travel week for me that week
), speaking on "Passing Messages" and "The Fallacies of Enterprise Systems"
- Oct 11, Orlando, Florida: VSLive! Orlando, talking on "Hosting ASP.NET"
- Oct 14-16, Seattle, Washington (my new hometown!): Pacific Northwest Software Symposium, another $NFJS show
- Oct 28-30, Reston, Virginia: Northern Virginia Software Symposium, another $NFJS show
- Dec 5, Salt Lake City, Utah: Utah .NET User Group, talking about... er... something interesting (we haven't decided what yet)
- Dec 13-17, Belgium: Javapolis, though... I'm not sure what I'm speaking on, and I'm not on the wiki (yet?)
And it's entirely possible I've left something out, so if you think I'm speaking at an event near you and I don't have it listed up there... email me? Please? 
Update: It looks like I won't be at the $NFJS Calgary show, despite my earlier having committed to it; the travel logistics required to get there are just horrendous. So no, I'm not doing NFJS Calgary, despite what it says there on the website.
|
|
Comment etiquette
|
|
If you're going to take the time to leave a comment, you obviously want your views to be heard, by either me or the people who read my blog, or both. So, then, take the time to make sure your views--and not just your opinions--are presented in the best light possible. Offer arguments, credible or otherwise. State your reasoning. Explain why your conclusions differ from mine. Don't just write "I don't agree" or something similar to that effect, because several things happen when you do this:
- Basically there's nothing for me (or others) to learn from it, so I pretty much ignore the comment.
- Because your email is (often) associated with the comment, it sorta makes you look bad.
- Worst of all (to me), you let go an opportunity for either or both of us to learn.
This isn't a general ban on comments--I could do that without posting. This is an attempt to point out that if I wanted the conversation to be one-way, I wouldn't leave comments turned on in the first place. This is the best mechanism I know of thus far for you to call me out on my arguments--why waste your time otherwise? 
Friday, August 26, 2005 9:16:25 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Thursday, August 25, 2005
|
There is no such thing as "Best Practices": Context Matters
|
|
James Bach recently blogged about something I've been saying in conversations with friends and conference attendees: there ain't no such thing as a "best practice".
He lays out his points in a letter to his blog readers, and I want to comment on a few of them.
First, "There are no best practices. By this I mean there is no practice that is better than all other possible practices, regardless of the context. In other words, no matter what the practice and how valuable it may be in one context, I can destroy it by altering things about the situation surrounding the practice." James hits the nail on the head with this one: any practice, taken out of context, can easily be turned from "best practice" to a "worst practice" without too much difficulty. The patterns guys had it down: A Pattern, or let's call it practice, so that we can talk more about concrete things, is a Solution to a Problem within a given Context that yields certain Consequences. You cannot avoid this basic relationship. (The patterns guys then wanted to take practices, examine them across domains, and find the commonality and elevate it so that we could apply them in a domain-independent manner; hence the reasoning behind the Rule of Three, which so many pattern "writers" seem to miss.) It makes sense, even on an intuitive level: I walk into a doctor's office, and say, "I have a cough". What's the Best Practice here? Meds? Diet and exercise? Immediate surgery? It clearly depends on the context--other symptoms, the pervasiveness of the cough, the reasons behind the cough, and so on. Doctors who fail to establish the Context before offering a Solution are often called Quacks... or sued for malpractice.
He goes on to say, "Although some things that don't exist can be useful as rhetorical signposts, "best practice" is not one of them. There is nothing honorable you get from pretending that a practice is best that you can't also get from suggesting that a practice may be good in a specified context, and making a case for that. Sure, there are dishonorable things you can get from "best practice" rhetoric-- say, causing a dull-witted client to give you money. If that has tempted you in the past, I urge you to reform." Unfortunately, the temptation is too strong, particularly for those who are pushing a new platform upon the world. Java got tremendous success from pushing patterns rather than canned solutions (and I think we pushed too many patterns, not enough practices, to be honest), and so now it seems a requirement for any new platform that in addition to the platform, you need to have an established set of practices with it to help guide the newbies to the platform. After all, how comforting does it sound when somebody seeking to sell you on a new platform, when asked "So how do I use this thing best?" turns to you and says, "We really don't know yet since there's not a critical mass of people using it yet"?
"It has a chilling effect on our progress as an intellectual craft when people pretend that a best practice exists. Best practice blather becomes a substitute for the more difficult, less glamorous, but ultimately more powerful idea of learning how to do your job. By "learning" I mean practicing the skills of identifying and solving patterns of problems we encounter as testers. Of course, that will involve patterns of behavior that we call "practices". I'm not against the idea of practices, I'm against pretense. Only through pretense can a practice that is interesting in a particular context becomes a "best practice" to which we all must bow down." Again, I'm fond of the patterns terminology here, because it clearly highlights the problem he's stating here: if we think we have a "Best Practice" to a particular problem, in other words, making it a two-part tuple, it becomes a deceptively simple list: we only need state all the Problems, and the Solutions will be apparent, since when would you choose not to use a "Best Practice"? When you list it out as a four-part tuple: Problem, Context, Solution and Consequences, it becomes more clear that a particular Problem doesn't have one "Best Practice", but depends entirely on Context and desired Consequences.
I would challenge anyone to name a "best practice" for which there is no situation which makes the "best practice" a "worst practice". To use James' example:
"A doctor who prescribes a drug without examining the patient is committing malpractice. Isn't that obvious? Would you respect such a doctor? Why should we respect people who prescribe practices without regard for the problems faced in a project? The answer comes back, "What if the doctor tells you to eat right and exercise?"
Easy--if the patient is in imminent danger of a heart attack, eating right and exercise is not going to prevent the heart attack; worse yet, the exercise could even trigger the attack. Such a doctor could easily be hoisted up on malpractice charges. My father suffered a massive coronary a few years back, and the doctor warned him very clearly that strenuous exercise was out until he'd recovered to a sufficient degree that his heart could take the strain. He's fine now--by that I mean no side effects, aside from 90-something percent scarring across his heart--but has to very carefully monitor his lifestyle. Which brings up a good point, as well: if you ignore the Context when discussing the Problem, how can you tell when the Context has changed (as they frequently do over time)?
People often cite EJB as a terrible technology. Bullsh*t. People who do that are missing the point. (Even Rod Johnson agrees with this point, or at least he did in a private conversation at The ServerSide Symposium in 2004.) The problem with EJB was that it was highly oversold: another case of "best practices" gone awry--most projects don't need EJB, despite the advice from EJB vendors. (Hmm....) EJB offers a much simpler programming model when dealing with two-phase commit programming against transactional resource managers, particularly given the context of seeking something industry-standard (for fears of new programmers having to burn all kinds of ramp-up time when they're hired). That's not really the problem space that Spring seeks to solve. (Leaving the reader to perhaps realize that maybe there's a place for both Spring and EJB in the world?)
Why the frenzy to use the term, if it has so many things wrong with it? Easy: "Best Practices" are easy to sell. Who wouldn't want to hire somebody who practices only "Best Practices"? Who would want to hire somebody who doesn't? It's an easy term for managers and HR practitioners to latch onto, and this is why most of the time you see unsophisticated speakers and tech leaders climbing all over themselves to use the term. Come on, admit it, which title sounds better and more "bang for your buck" at a conference? "J2EE Best Practices" or "Patterns of J2EE"? Most developers will pick the first, every time. And, worse yet, not realize they're being sold a bill of goods.
If you find yourself tempted to use the term, stop and examine your rationale for doing so. Are you really asking somebody what the best way to use something is, without regard to context? Or are you implicitly seeking to push your own agenda? As a speaker, I routinely get questions like, "Is it a best practice to ... ?" that are followed up by, "But what about when ....?", in essence seeking to know if I change my advice when the Context is different than what they think I'm thinking about. And usually, yes, it does. 
Challenge to the reader: the next time you see somebody use the term, "Best Practice", ask yourself (or them) if you can come up with a situation (a Context) where it would be a "Worst Practice" instead. If you can't, or if they can't, it's probably indicative that you--or they--don't quite "get it" yet. Or, more likely, that they've just never seen a situation where it wouldn't be applicable... which then makes me question exactly how much this particular practice has been used. Think it's a silly exercise? Almost all of the great technology books in our industry have either explicitly or implicitly brought this point to the forefront of the book, even to the point where the contradict themselves sometimes. Still not convinced? Then how about this: after you can begin to see the separation between Problem, Solution, Context, and Consequences, you may be able to stop listening to "experts" and start making up your own mind.
Context matters.
Thursday, August 25, 2005 7:11:34 PM (Pacific Daylight Time, UTC-07:00)
|
|
|
WS-Addressing, the complexity-to-power ratio, and REST
|
|
Elliotte Rusty Harold blogged about the WS-Addressing specifications reaching Candidate Recommendation status, and did a bit of editorializing along the way:
These specs are seeing some serious pushback within the W3C. The problem is that there already is an addressing system for the Web. It's called the URI, and it's not at all clear that web services addressing does anything beyond URIs do except add complexity. In fact, it's pretty clear that it doesn't do anything except add complexity.
Here's the problem. Web Services Addressing "defines two constructs, message addressing properties and endpoint references, that normalize the information typically provided by transport protocols and messaging systems in a way that is independent of any particular transport or messaging system." In other words this is another example of the excessive genericity problem, just like DOM, and remember how well that worked. One of the big fundamental problems with DOM was that they tried to develop an architecture that could work for all conceivable programming languages; but developers don't want and don't need an API for all programming languages. they want an API that's tailored to their own programming language. This is why language-specific libraries like XOM and Amara are so much easier to use and more productive than DOM.
Web Services Addressing is trying to define an addressing scheme that can work over HTTP, SMTP, FTP, and any other protocol you can imagine. However, each of these protocols already have their own addressing systems. Developers working with these protocols don't want and don't need a different addressing system that's marginally more compatible with some protocol they're not using in exchange for substantially less compatibility with the protocol they are using. Besides nobody's actually doing web services over anything except HTTP anyway. Doesn't it just make more sense to use the well understood, already implemented debugged HTTP architecture for this instead of inventing something new? Frankly, no. Not everything carries well over HTTP, and frankly I'm surprised that Elliotte doesn't agree with that. HTTP works well as a point-to-point, client-initiated request/response protocol, but there are a lot of situations where a point-to-point, client-initiated, request/response protocol simply doesn't cut it for large-scale integration work.
For example, consider your canonical "push" model; as it stands right now, there is no way to do the virtual equivalent of a classroom environment: multiple clients (students) all passively receiving content distributed in packets from the server (instructor). What's more, that distribution model is essentially a broadcast scenario with zero guarantees of delivery--if a student nods off in class, does the instructor care? Not normally, no, and certainly not to the expense of the other students in class. Broadcast scenarios are a powerful argument against HTTP, since to try and replicate this either
- the clients have to poll continuously for updates, or
- the server has to become the client, and constantly "push" the various elements out to the clients... er, servers... whatever, taking whatever firewall/security issues might be in between them into account (which is why the client-polling scneario is usually the way people go)
Now, I recognize that not many people are really interested in XML service-based classrooms, but this model also has powerful ramifications for your classic Distributed Observer pattern, where multiple clients want to receive notifications regarding a change in some resource state on the server. Should the server really block while it makes individual point-to-point client-initiated request/response calls? (Remember, if all of this is going over HTTP, it means that the Observers need to be servers with active endpoints always listening for callbacks from the server, or else we have to go to a VERY complicated muxing scheme where the callbacks get piggybacked on top of an orthogonal response packet, which also destroys any guarantees we might want of timely notifications.)
Look, at the end of the day, the WS-Addressing spec only requires the Action header, which serves the exact same role as the HTTP verb does: it simply provides a way to describe what the intended action for the message should be. Everything else is optional in the specification, including the To, From, ReplyTo or FaultTo headers (which use the EndpointReferences, the "virtual addresses" ERH is railing about)--which enable flexibility in message responses that HTTP simply cannot provide, highly useful in a workflow situation--or the MessageId/CorrelatesTo headers--which provide the ability to "thread" messages together, something that HTTP could only do with the introduction of cookies, something that Fielding argues against in a major way as it destroys the basic principles of a REST-based system.
In particular, I take issue with the idea that "nobody's actually doing web services over anything except HTTP anyway". If that's the case, somebody had better tell the messaging vendors, like IBM or Sonic or TIBCO or Fiorano, because they seem to be investing a lot into the XML services standards in an effort to help build that exact integration infrastructure that CxOs have been pursuing with all the zeal of the Holy Grail for about forty years now. I can think of four consulting clients off the top of my head that are using XML services over something other than HTTP, and will probably continue to do so for a long time to come. Guess they must just be trying to overcomplicate their lives, even though SOAP-over-TCP and SOAP-over-FTP actually cut the lines of code they had to maintain because they no longer had to build a complicated polling process. And as for "Doesn't it just make more sense to use the well understood, already implemented debugged HTTP architecture for this instead of inventing something new?", shortly, no, it doesn't. There's no sense in trying to take bits that were designed for a distributed hypermedia system (Fielding's words, not mine) and trying to bend it to fit a problem space that isn't distributed hypermedia. Can we learn from the REST architectural style? Absolutely--and the new WS-* specs, including SOAP, do exactly that, favoring self-descriptive messages over RPC calls as the principal abstraction to deal with. But does that mean we tie ourselves solely to HTTP? Oh, hell no.
Barely hidden between the lines in Elliotte's post is a general accusation that the WS-* guys are deliberately overcomplicating things. Frankly, I think that's an unfair categorization of what's been going on. SOAP 1.1 was complex, oh, Lord yes. SOAP 1.2 is actually fairly simple, all things considered, despite the perception you might get when you look at the spec and see three parts and a hundred or so pages instead of a single 30-page document (as SOAP 1.1 was). SOAP 1.2 standardizes a basic message format, with room for extensions (where the rest of the WS-* stack goes, for the most part), and provides a standard fault structure so that not everybody needs to define their own custom fault formats. (This is important if the fault is at the infrastructural level, not at the application level.) Everything else layers directly on top of SOAP, and frankly, if you don't need it, don't use it--the WS-* specs try very hard to be composable, meaning if you don't need a particular element, you don't use it and you don't pay for it. In fact, some of these specs (WS-Eventing, for example) are simple enough that you could implement it by hand without any help (Axis, BEA, etc) whatsoever.
Don't let a tempting political quantity (the basic desire to mistrust the big vendors and think they're just out the screw the little guy) cloud your vision over what's going on in the industry. The big vendors may very well be out to screw the little guy, but that doens't mean that everything they do isn't useful. If you build a REST-like XML service, you're actually following right into the "new" XML service model, and if you slap a SOAP:Body around your message and a SOAP:Envelope around that, you'll be wire-compatible with other SOAP 1.2 endpoints. Even better, if and when you need reliability, workflow capabilities, or integration with somebody else's WS-* stack, you're already primed to go. And wasn't that the point of all this stuff in the first place?
|
|
Welcome to JSR-277!
|
|
Although I've known for a bit, I couldn't say anything until now, when I just received the official welcoming letter: I'm a part of the JSR-277 Expert Group, the so-called "Java Module System" JSR. Although you can read the full spiel on the JCP website, the nuts-and-bolts part of this story is simple: we (or at least, I) want to fix the horribly busted component model in Java. Or, rather, the lack of any such thing, beyond what the J2EE world offers (which isn't much).
To put it into EG Lead Stanley Ho's words from the JSR-277 home page,
The specification of the Java Module System should define an infrastructure that addresses the above issues. Its components are likely to include:
- A distribution format (i.e., a Java module) and its metadata as a unit of delivery for packaging collections of Java code and related resources. The metadata would contain information about a module, the resources within the module, and its dependencies upon other modules. The metadata would also include an export list to restrict resources from being exposed outside the module unintentionally. The metadata may allow subset of exposed resources to be used by other modules selectively.
- A versioning scheme that defines how a module declares its own version as well its versioned dependencies upon other modules.
- A repository for storing and retrieving modules on the machine with versioning and namespaces isolation support.
- Runtime support in the application launcher and class loaders for the discovery, loading, and integrity checking of modules.
- A set of support tools, including packaging tools as well as repository tools to support module installation and removal.
We also expect the Java Module System to expose the public J2SE APIs as a virtual module in order to prevent unwanted usage of the private APIs in the implementation. In other words, a lot I've long railed about being broken in the Java runtime. About the only thing I *wish* we could do that's out-of-scope to the JSR is to fix the javac compiler to cease emitting .class files directly, but instead consider .class files to be the moral equivalent of C/C++-compiled .obj files, and automagically do that final step and turn it into a .jar file right out of the box. (Out of curiosity, is there anybody out there who doesn't immediately jar up your .class files?)
There's some high-powered folks on this JSR, as there was on my last EG, such as Stu Halloway, David Bock, Doug Lea, Sam Pullara and Hani Suleiman (gotta be careful about emails to Hani, though, or I might find myself the subject of a weblog entry and I dunno if my fragile ego could handle that...). I'm looking forward to working on a JSR with Stu, with whom I've not closely worked since Stu left DevelopMentor to go his own path, particularly since I've been... err... disagreeable, shall we say?... with his business partner. Not only that, Stu appears to have taken a deep hit of the dynamically-typed languages Kool-Ade, and I always welcome reasoned debate with somebody who's perspective wildly differs from mine.
Once again, I think my major contribution will be the experience of the .NET world, and their experiences with assemblies. It will be particularly interesting to see how Java Modules will or won't closely emulate assemblies, and to be 100% honest with you I'm not sure if it would be a Good Thing or not if they did. I think there's definitely some goodness to how assemblies work, but there's also some interesting feedback filtering through the collective .NET unconscious that seems to disagree with my own perceptions.
All in all, it's going to be an interesting ride. Wish us luck--this is probably one of the more influential JSRs in the JCP for Dolphin, as it'll change the packaging and deployment models for both J2SE and J2EE (and beyond), so if we screw this up.... *shudder*
BTW, if you know of a good component model beyond Eclipse, NetBeans, .NET or OSGi, please drop me email and tell me why you think it's something I should look into. I won't promise anything, but obviously the more experience we can draw upon, the better the chance we have of the final results not... well, not sucking.
Java/J2EE
Thursday, August 25, 2005 5:42:51 PM (Pacific Daylight Time, UTC-07:00)
|
|
|
Adopting Rails... or Ruby... or anything else, for that matter
|
|
Duane Gran emailed me with his thoughts on adopting Ruby-and-Rails into his shop, only his thoughts on the matter are a bit different from the usual rant; he's looking at it from the management perspective, and has some good ideas on when and why to adopt... or not to adopt... a new programming language. Specifically, he spells out:
The decision to change programming languages, databases and operating systems shouldn't be taken lightly, but when the issue comes up the approach should be analytic. Be wary of resume-driven development initiatives, architectural advice from vendors, marketing hype and buzzword compliance. That your development team is more productive with the new technology is all that matters. ... I suggest changing architectures only when the following factors align:
- The technology is proven in your development environment
- The installed user base is small for your application
- You are still in a development or prototype stage that won't endanger a production system
- Your developers want to learn the technology for the right reasons and they have a firm grasp of the code base
Follow this model and you will avoid untold frustrations that lie in wait. Transitioning to Ruby on Rails worked fantastically for our group and it may well do so for yours as well, but proceed analytically and demonstrate value from the transition before making a full leap.
I like that list. I could probably add to it, with concerns whether the technology will be somehow integratable/interoperable from your legacy platforms, but I think that these issues are probably the first hurdle to pass--and, frankly, I think will be the hardest hurdle to pass, particularly given his caution against "resume-driven development initiatives". (I like that phrasology, Duane--don't be too surprised if you hear it on an $NFJS panel sometime. 
.NET | C++ | Java/J2EE | Ruby
Thursday, August 25, 2005 4:03:29 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Monday, August 22, 2005
|
When do you use XML, again?
|
|
So I'm flipping through some old weblog entries, and I run across this one:
So when is it a good idea to use XML for your data? The easy answer is that you should use XML when it is likely to be easier (in the long run) than creating your own parser. Using XML carries some cost. XML is verbose, and parsing is guaranteed to be slower than a custom parser. Why is XML such the rage then? Aside from the hype there is one very good reason to use XML. For many types of data, it is easier to just load the data into a DOM and extract the information from that, than it is to write a custom parser. That means less time spent debugging code, more time spent focusing on the problem at hand.
Gotta say, no way. XML isn't just a format designed to avoid having to write a parser; going down this path may seem like a good idea in the beginning, but over time it's eventually going to bite you in the ass in a big way--just ask James Duncan Davidson, the original creator of Ant, who later came to admit that
- He originally chose to use XML as the format for Ant scripts because he didn't want to write a parser, and
- He really regrets it and apologizes to the Java community at large for it.
(Source: paraphrasing from personal communication and Pragmatic Project Automation, by Mike Clark).
The problem, in the case of Ant--and its successors, like MSBuild--in using XML is that it is a strictly-hierarchical format, and not everything follows a strictly hierarchical format (even though it might seem to at first). More importantly, XML is a hideously verbose format, and the "self-descriptive" tags that everybody blathers on about are only self-descriptive to carbon-based life forms (and then only if semantically-rich terms are used for the tag names). For example, does this "self-descriptive" XML have any meaning to you?
<p><a>34</a><s>046604143</s><ph>42049941499<ph></p>
It obviously avoids the verbosity that frequently plagues XML, but clearly surrenders a lot of the self-descriptiveness as a result.
So when is it a good idea to use XML for your data? My criteria are a bit more stringent:
- When your data is naturally hierarchical to begin with
- When exchange with foreign platforms (which is to say, platforms not native to what you're currently authoring in) is important
- When pre-existing tool support (XSLT, XML viewers, import/export utilities, etc) is of paramount importance
Still wanting to use XML to avoid having to write a parser? Fine, do so, but make sure to set a timer somewhere in your code that will delete the data file in a year or so, or else risk making the same mistakes Ant did....
By the way, scripting languages (like Ruby, Python or JavaScript) make a terribly convenient way to do data storage/manipulation that still doesn't require writing a parser or custom data format--witness the astounding success of Ruby-on-Rails in this area to see what I mean. Combine this with the ability to embed them in your .NET, Java or C++ code, and you have a really strong argument against using XML to "avoid writing a parser". Look at what Groovy does for Ant scripts, for example (Pragmatic Project Automation).
|
|
Why .NET developers should learn Java, and vice versa
|
|
John Robbins recently blogged about an "amazingly cool" bit of .NET TraceListener magic sent to him in an email:
Josh Einstein sent me a mail about his amazing TerminalTraceListener. If you add TerminalTraceListener to your application, you can telnet into your application and monitor tracing live no matter where it is. How amazingly cool is that!? Josh also added a second TraceListener, SyslogTraceListener, that pumps the traces to Kiwi Syslog Daemon.
John, I deeply apologize for not bringing it to your attention earlier, but $g(log4j) has been doing this for years. In fact, so has $g(log4net), if I'm not mistaken.
What this really underscores, however, is how John's debugging capabilities have been limited (however slightly) by his unawareness of the Java space. John is not a stupid person by any stretch of the imagination--his books on debugging leave me in stunned jaw-dropping silence every time I read them--but it sounds like he thinks could have used these two long before now, and he could have had them (without even having to write them, in fact) had he known about log4j or log4net before now.
Which leads me back to my point: you don't have to be a hard-core Java developer to learn something from the Java community, and vice versa. Take a day or two, learn the platform you don't routinely write code on, and take a day or so every month to look around at the tools and technologies that are out there. I think you'll be amazed at how rich and powerful the "other guys" are, and your own skills will grow immeasurably as a result.
.NET | Java/J2EE
Monday, August 22, 2005 3:31:29 AM (Pacific Daylight Time, UTC-07:00)
|
|
|
Book Review: Pragmatic Project Automation
|
|
A bit late, but I realized after I posted the Recommended Reading List that I forgot to add Mike Clark's Pragmatic Project Automation, a great resource for ideas on how to automate various parts of your build cycle... and, more importantly, why this is such a necessary step. Although nominally a Java book, there's really nothing in here that couldn't also be adopted to a .NET environment, particularly now that $g(NAnt) and $g(MSBuild) are prevalent in .NET development shops all over the planet.
Most importantly, Mike indirectly points out a great lesson when he uses $g(Groovy) to script $g(Ant) builds: that you don't have to stick with just the tools that are given to you. Automation can take place in a variety of ways, and scripting languages (like Groovy, or Ruby, or Python...) are a great way to drive lower-level tools like Ant. Stu Halloway has begun talking about the same concept when he discusses "Unit Testing with Jython" at the $NFJS shows. Coming from the .NET space? Then think about $g(IronPython), or even the JScript implementation that comes out of the box with Visual Studio.
All in all, a highly-recommended read.
|
|
Parrot interoperability
|
|
Dion blogged about $g(Parrot) a while back, and it triggered an interesting thought: we already have IKVM, a JVM-running-on-the-CLR, is it possible and/or practical to do a Parrot-running-on-the-CLR or Parrot-running-on-the-JVM? That would do some interesting kinds of interoperability scenarios between Parrot's targeted dynamic languages and the library-rich platforms of Java and .NET....
.NET | Java/J2EE | Ruby
Monday, August 22, 2005 3:31:10 AM (Pacific Daylight Time, UTC-07:00)
|
|
 Sunday, August 21, 2005
|
Recommended Reading List (old version)
|
|
(Note that this is a reprint, so to speak, of the same entry on the old weblog, but I wanted to kick the Reading category off with a reprise of what I'd written before.)
I've been asked on several occasions (from students, from blog readers, and from a few friends who happen to be in the business) what my recommended reading list is. I've never really put one together formally, instead just sort of relying on impromptu answers that cover some of my absolute favorites and a few that just leap to mind at the time.
Enough is enough. It's time for me to post my recommended reading list, broken out for both Java and .NET programmers. (If you're of one camp, it's still worth reading books on the other camp's list, since the two environments really are Evil Twin Brothers.) And I've left my own books off the list, because I think it's rather forward of me to recommend them as recommended reading--naturally, I think they're all good, but whether or not they make the cut of "recommended reading" is for others to weigh in on, not me (at least not here). (Update: several commenters on the old blog suggested it was not out of line to recommend my own books if I thought they were worth recommending, so I added them.)
Java Recommended Reading list:
- Effective Java by Bloch.
- Java Puzzlers by Bloch and Gafter. You think you know the Java language? Try it. (Makes for great interview question fodder, and for that reason alone practicing Java programmers should have a copy on their shelf.)
- Effective Enterprise Java by Neward. (Had to do it.
)
- Concurrent Programming in Java (2nd Ed) by Lea.
- Either Inside Java2 Platform Security by Gong or Java Security (2nd Ed) by Oaks.
- Component Development for the Java Platform by Halloway.
- Inside the Java2 Virtual Machine by Venners.
- Java Development with Ant by Hatcher and Loughran.
- Either Java RMI by Grosso or java.rmi by McNiff and Pitt.
- Server-Based Java Programming by Neward. For obvious reasons.
Actually, I still think this book is applicable if you want to understand the reasons why an app server makes some of the restrictions that it does, but I freely admit that I don't think I did a great job of "closing the loop" on that and finishing the book with a good summary that ties everything together. Ah, retrospect....
- Servlets and Java Server Pages by Jones and Falkner, possibly Java Servlet Programming (2nd Ed) by Hunter, if you aren't planning to use JSP. (Jason's legendary bias against JSP, right or wrong, puts him somewhat out of tune with what a majority of Java web-client shops are doing. That said, it's a great servlets resource.)
- AspectJ in Action by Laddad. AspectJ represents the best of the AOP solutions, IMHO, and this book represents the best of the AspectJ books available.
.NET Recommended Reading list:
- C# In a Nutshell (2nd Ed) by Drayton, Albahari, and Neward. For obvious reasons.
- Advanced .NET Remoting by Rammer.
- Essential ADO.NET by Beauchemin.
- Inside Microsoft .NET IL Assembler by Lidin.
- SSCLI Essentials by Stutz, Neward and Shilling. For obvious reasons.
- Debugging Applications by Robbins.
- Inside Windows 2000 by Russinovich and Solomon.
- Essential COM by Box. (Yes, I mean Essential COM and not his more recent Essential .NET book. The first chapter of Essential COM is probably the best well-written technical prose I've ever read in my life, and everybody who ever wanted to write reusable components in C++ needs to read it to understand why C++ failed so miserably at that goal. Once you've seen that, you're ready to understand why components are so powerful and so necessary.)
- Essential ASP.NET by Onion.
- Expert C# Business Objects or Expert VB Business Objects, by Lhotka. Not an intro to business objects, per se, but a great read on how to build a framework. Pay close attention to how Rocky handles distribution; he avoids the canonical problems of "distributed objects" by not distributing objects, but instead making them mobile objects.
- The Common Language Infrastructure Annotated Standard by Miller
- Programming in the .NET Environment by Watkins et al.
C++ Recommended Reading list: (For the twelve people left in the world still writing C++ code, anyway.)
- The C++ Programming Language (3rd Ed) by Stroustrup.
- Effective C++ (1st, 2nd or 3rd Ed) by Meyers.
- More Effective C++ by Meyers.
- Effective STL by Meyers.
- Inside the C++ Object Model by Lippmann. You don't know how C++ works until you've read this cover to cover. Twice. And peeked at everything under the hood with a debugger, just to make sure Stan's right. Seriously.
Database/Relational Storage Recommended Reading list:
- Introduction to Database Systems (8th Ed) by Date. Heavy on theory, and for that reason alone should be read at least once by any practicing programmer who thinks they understand SQL and the relational world.
- SQL for Smarties (3rd Ed) by Celko. Actually, you need to own just about everything by Celko.
- Principles of Transaction Processing by Bernstein and Newcomer.
- Transaction Processing: Concepts and Techniques by Gray and Reuter. What to read when you're done with the Bernstein and Newcomer book and still want to know more about the Zen of Transactional Processing.
Security-related Recommended Reading list:
- Secrets and Lies by Schneier.
- Either Cryptography Decrypted by (can't remember the name offhand), Practical Cryptography by Schneier and Ferguson, or Applied Cryptography (2nd Ed) by Schneier. The first is a lightweight introduction to the subject, the second is a more detailed introspection, the third required reading for anybody who wants to be a security wonk.
- The Code Book by Singh.
- Hacking Exposed (5th Ed), by McClure, et al.
- Exploting Software, by Hogland and McGraw. The most fun book in the list, if you ask me.
- Reversing by Eilam. Who says unmanaged code is "safe from reverse-engineering"?
- The Art of Deception, by Mitnick
Operating System/Platform Reading list:
- Windows Internals (4th Ed) by Russinovich and Solomon. Actually, any of the last three editions (2nd, 3rd, 4th) is awesome, so look for 3rd Ed in a bargain bin and pick up a great bargain.
- Operating Systems (2nd Ed) by Tanenbaum. The original "Minix" book. Taught me the basics of how an O/S works, and the basic concepts are still applicable to this day.
Platform-agnostic Recommended Reading list:
- Design and Evolution of C++ by Stroustrup. It's fascinating hearing how a language develops over time, and what was behind some of the decisions in the features of the language. For example, why did multiple inheritance come before templates or RTTI? Not because it was more important, but because Stroustrup wanted to tackle MI first because he wasn't sure if or how he could do it. He describes that as a great regret, that he didn't do templates first.
- Component Software (2nd Ed) by Szyperski.
- Rapid Development by McConnell. Read this before you read any of the Extreme Programming books, because this book describes a whole taxonomy of what I think a lot of people are reaching for in agile and other methodologies.
- The Inmates Are Running the Asylum by Cooper.
- The Invisible Computer by Norman.
- Refactoring by Fowler.
- Design Patterns by Gamma, Helm, Johnson and Vlissides.
- Pattern Oriented Software Architecture, Vol 1 by Stal et al.
- Pattern Oriented Software Architecture, Vol 2 by Schmidt et al.
- Patterns of Enterprise Application Architecture by Fowler.
- Enterprise Integration Patterns by Hohpe and Woolf. Excellent discussion of message-based architecture. I personally think the title is something of a misnomer, but it's understandable since message-oriented communication is the easiest means by which to integrate heterogeneous systems.
Note that this list will undergo revision and change as I continue, so I'm putting a link to this item in the links column in the sidepanel to the left for easy reference. For now, I'm just listing them out as they come to mind. Later, if I have time, I'll put paragraphs of detail behind them so you can know why I recommend them. (Updated on 13 Feb 2002) (Moved to this weblog 21 Aug 2005) (Updated 5 Oct 2005)
Look for more book reviews and recommended reading via the "Reading" category on the RSS feeds. There's undoubtedly titles that I'm forgetting, and I'm hoping I'll get around to blogging more about the books I'm reading now, including Ruby (the Pickaxe book and the Rails book), some other titles in the Pragmatic series, as well as some WS-*-related stuff and (of course) the staple C# and Java stuff. And of course I'm always open to suggestions of new and interesting technical titles to peruse....
Update: Steven Rockarts pointed out that Rocky's "Objects" books are missing, as is Fritz's Essential ASP.NET. Added. (He also lists Object Thinking, by West, but I don't care for that book--too Zen, I think, for most readers.)
|
 Friday, August 19, 2005
|
Rails... finis?
|
|
Well, apparently I've created quite a stir in the blogspace by not immediately rushing to embrace Ruby-on-Rails, and I'm of two minds as to the larger impact.
For starters, allow me to respond, one last time, to what Justin and Dion and Glenn have written:
- "Pretty clearly, Rails' biggest benefit is Ruby itself. ... Dynamic languages like Ruby provide for eloquence of expression and compile-/run-/deploy-time extension of the core framework abstractions. ... extending classes at runtime ... is powerful, and hard to do in a statically typed language." Actually, Justin, as I think some of the feature set listed for C# 3.0 demonstrates, it's not that hard to do at all in a statically typed language, particularly considering that we don't want to do it at runtime, but at compile-time, so to speak. (I've yet to see a Rails demonstration that changes the type at runtime--it's all been done at edit-time, which in Ruby is the logical equivlent of compile-time.)
- "Lots of people have written about Ruby’s suitability for creating DSLs. When it comes down to it, Ruby’s extensibility and flexibility put it in a class with Lisp, Python and Perl and separate from byte-code-language-X for creating custom syntax. For me personally, extending the base constructs of Ruby to support new, app specific capabilities, makes my job 40 times easier." Frankly, this again smacks of Ruby, not Rails, to me, because I don't consider what Justin is creating in his example to be an example of DSLs. Useful, certainly, powerful, certainly, but not really in keeping with the DSL concept, at least not as it's been discussed up until this point.
- "As I said last time, and as Ted agreed, it is high time for web apps to act like web apps. I want my framework to deliver the HTML over HTTP experience as though that’s what I intended all along to deliver. If it gives me nice ways to bridge the server and client that make it feel a little more tightly integrate (AJaX, anybody?), the more the better. What I DON’T want to forget about is that I’m on the web. Rails strikes, for me, the exact right balance between abstraction and transparency." POWA: good. Rails-as-best-expression-of-POWA: arguable, but not something I want to spend a great deal of time arguing, to be blunt about it.
- "Rails’ convention-over-configuration is a startup-enabling technology. By startup, I don’t mean a new company, I mean a new project. Part of the Agile methodology’s premise is that you get the framework of the app up and runnning as fast as possible (during the first iteration). Then, add on the features. Rails’ convention based approach makes this an absolute lead-pipe cinch. I never question any more how long it will take me to get the front-to-back chassis in place. Rails all but guarantees I’ll be finished in the first iteration, often in the first couple of days. Will I keep that chassis as is for the rest of the project? Of course not. The scaffolding is just that — a shell that allows you to visualize the general shape of the application before you’ve put in all the foundation and walls and pretty siding. As you fill that stuff in, the scaffolding comes down, and you are left with real, working code. Yet all along, you’ve been able to demonstrate to your customer what the final thing might look like. Might be a little fuzzy along the way, but the end product won’t be a total surprise." OK, here we get to a nuts-and-bolts point: Rails as a startup-enabling technology is a good thing. But projects will not always be startup projects. And in particular, this is exactly the path that servlets and JSPs took, and this is exactly when and where the complexity kicked in--people discovered that they needed something more complex than startup-enabling technology as their systems scaled up, not in terms of concurrent users, but in terms of complexity to the rest of their back-end systems. Particularly if you've ever had to rewrite an ASP system in Java servlets--and by the way, had to preserve the deep links scattered all across the Internet--you've come to really appreciate the flexibility in URL-to-code configuration that the servlet environment gives you. Let's NOT throw the baby out with the bathwater when we toss away servlets/JSP in exchange for something that helps us get the easiest 80% of the app done more quickly. Remember the Golden Rule of Software Estimation: "The first 80% of the app will take 80% of the time. The next 20% of the app will also take 80% of the time." It's never the first 80% of the app that I worry about; it's the last 20% that concerns me.
- "Lastly, but certainly not least, Rails gives you speed. I simply have never worked in a web app framework that enabled me to move at such a controlled velocity. I may have moved faster in the past (particularly using generated ASP.NET pages) but I never had the tools built in to ensure I was doing a decent job. Not only is Rails a highly productive environment, but it almost forces you to take a test-and-prove approach to development, if through nothing more than guilt. (Hey, look, you just generated a new controller, and I put all these handy tests down here for you to use! What, you aren’t going to use them? What kind of lame-o are you?!?!)" This is the part I can least speak to, as I've not experienced Rails directly yet, not in any form of "production" capacity, anyway. (I plan to, though--my next book, one which I'll announce soon and will be in Dave's Pragmatic series, will have a Ruby/Rails component to it, I'm certain of it.) So I'll have to defer to Justin's experience here, though I will close with the thought that I wonder if we couldn't have the same kind of speed in Java or .NET if we built the surrounding scaffolding to do the same things that Rails does.
- "I think that Ted will end up putting the Rails and Ruby books back on his shelf, if for no other reason than he’s never thrown away a book in his life. However, I believe that Ted really values technologies that offer something new to developers and their customers. Rails is clearly, for me, one of those technologies, and I think that Ted believes it too, really. He just likes to have blog-offs." Well, I won't disagree with Justin's point that I like to see what smart people have to say on topics that I disagree with, and frankly, don't expect the "blog-offs" to stop anytime soon, as I've learned a lot just from this debate. And yes, Justin's right, I've never yet thrown a book away, so the Rails book will end up back on my shelf eventually. But it's really a larger question of how much time I should spend on the subject, and I think there's enough intriguing elements here (mostly dealing with the fact that it's Ruby) to justify spending more time learning it. But don't expect to see me recommending Rails in a production capacity any time soon--my clients tend to be the large-scale enterprise folks that Justin mentions, and as a result I probably won't be using Rails "in anger" any time soon.
- Glenn said, "What’s Rails about?
- "It’s about Ruby and the things that a scripting language can do that a compiled, statically-typed language can’t." Again, Glenn, I'm concerned with writing off statically-typed languages as being simply "unable" to do some of the things that Ruby is doing--I believe that to make that argument shortchanges the statically-typed language just as much as arguing that the dynamically-typed language "can't perform" does.
- "It’s about confirming some of the earliest thinking about frameworks: that they should be extracted from well-designed applications, rather than being designed on their own." Amen to that! I've watched thousands of "reusable frameworks" built from scratch, without even a project to build them around, and they showed it. (I'll even admit to building a few myself.) There's a great quote I heard someplace in the C++ days--wish I could remember who said it--that says, "We need to make something usable before we can make it reusable". Learn it, love it, live it. And if that is Rails' greatest contribution to the Java space, then count me in as a fan.
- "It’s about demonstrating the fundamental importance of the DRY principle for software design. (Bruce Eckel calls it "the most fundamental concept in computing.")" Well, certainly I applaud the idea of DRY and Once-And-Only-Once as core principles, but let's also not forget the power of the Level of Indirection. Bruce Eckel may disagree, but I find THAT to be the most fundamental concept in computing.
- "Oh … and it’s about bringing the pendulum back away from the layers-upon-layers default approach in Java projects." And, again, hallelujah! Say it loud, say it proud.
- "For some time many frameworks have been going to the JSF extreme, and Rails has come along to give a great balance. Hacking away at JSPs, or PHP files just becomes a mess quickly. We all learned that. Then we started working with simple MVC things which was fine, and it got complicated. Rails is rebalancing things!!!" Sure, but let's not go to the opposite extreme in the rebalancing--there is value in that complexity in the servlet/JSP space: unless you believe that smart people seek to create complexity just for the hell of it, then you have to believe that the complexity that was added to the servlet/JSP space was introduced there for a reason. If, by the way, you choose to believe that the servlet/JSP community added that complexity for no good reason whatsoever, then you and I simply have to agree to disagree on that point. Has the web framework space gotten too complicated? Sure--everybody's trying to put THEIR layer of abstraction on top of servlets/JSP (and JSF quite clearly fits into this category), and that, to me, is a mistake, but again, let's not throw out the baby with the bathwater. Let's not chuck servlets/JSP just because certain people are trying to impose their abstractions on top of it.
- "Come on dood. You really think that you would want to build a web application in pure Servlets?" Dion, I never said that, nor do I believe that. (Although, quite frankly, I think you canget some distance with pure servlets and some good library support, such as $g(Velocity). Hey, if template files are good enough for Rails...) This isn't a black-or-white discussion--it isn't Rails vs. Pure Servlets vs. JSF. It's a continuum, and Rails fits on an end of the continuum that I find to be too naive and simplistic to fit the needs of the companies that I consult for. Your experience may be different, and if it is, wahoo!
My second concern, however, is the larger issue: I can't really recommend or get my heart behind a technology until I've seen it applied to several full-lifecycle projects (not necessarily my own, but others' are acceptable) so that I have something to examine and see where the strong points and weak points are. I know that Rails grew out of a website, then another and another, for a website design company, and that in of itself gives me a good feeling, but until Rails starts to go beyond the simple webapp-on-a-database scenario, I won't really give it much credit beyond something to compete with a ColdFusion or PHP. So, to all you Rails-heads, check back with me in a year, show me the wide variety of sites built with Rails, and then (maybe) I'll be willing to be convinced otherwise. Until then, well.... happy coding. 
Java/J2EE | Ruby
Friday, August 19, 2005 10:09:30 PM (Pacific Daylight Time, UTC-07:00)
|
|
 Wednesday, August 17, 2005
|
More on Rails
|
|
It appears that a couple of my so-called friends are expressing surprise(?) or condemnation(?) over the fact that I didn't fall under the spell of Ruby-on-Rails at the $NFJS Austin show. As the great comic Steve Martin used to say, "Well excuuuuuuuse me!" 
Dion first takes a couple of cheap shots:
Firstly, you can't say much for Ted wrt taste... I mean he is running that .NET blog software now ;) Dude, you have NO idea how much simpler and easier my life is now thanks to dasBlog. So hush.
Secondly, I think Ted hit the nail on the head and didn't even realise it ... I think the Java world took this [greater need for configuration] waaaay to far. Abstractions upon abstractions. We forgot that web frameworks ARE FOR THE WEB!!! I don't remember ever saying anything otherwise, nor did I anywhere endorse any of the particular Java web frameworks that have sprung up like weeds, including JSF, which Dion goes on to imply I'm a fan of with:
Before you look around we have JavaServer Faces, which "features" that you don't just get to write out HTML. Sounds great on paper. I still hear people talking about how they will be able to just flip on a different Renderer and they will have a mobile application. Of course, in reality a mobile application is very different. You care about different things. Dude! I said the same thing waaaay back when JSF first came out, that it seeks to create a programming model similar to that of a rich GUI app over a technology that looks nothing like a GUI app. There's no argument here. But the idea that somehow "it's Rails or it's JSF" is a HUGE logical fallacy, and one that frankly I'm surprised Dion even hints at. I have no value judgment to make a la JSF, as I've not done anything with it, other than I'm worried about the implicit inefficiencies that JSF was in danger of creating (as WebForms do in .NET). People I know and respect (most importantly, David Geary, a one-time huge proponent of JSF) are critiquing JSF, and for now that's something I'll let them do, as for me to comment on JSF in detail would be speaking from ignorance. That said, though....
I want a web framework that lets me work with web technology (HTML is one of them ;), but gives me a nice clean way to do this. Allow me to introduce you to this really cool little technology, Dion: it's called servlets, and it's so tightly coupled to HTTP that it's frightening. I mean, there's really no way you could ever hide the round trips implicit in HTTP, nor could you port a servlet app to become a mobile app or a GUI app. They do reloading of compiled code on the fly, and they have a relatively simple configuration model (particularly if you don't make heavy use of exotic features like security models, which you won't because you don't even have them in Rails so you won't miss 'em, right?). Couple this with some JSP and good XDoclet-based code-generation, and you've a pretty interesting system right there....
In my experience, I like to have simple tools which just work, but if the hardest part of your application is the web framework, you are lucky! I heartily agree, and frankly, I find that "Servlets + JSP" fit into that category of "simple tools that just work". That's a value judgment, and I won't find fault with anybody who claims that the servlet+JSP space is too complicated--but that said, don't come crying back to us when Rails doesn't let you do URLs the way God and Tim Berners-Lee intended. Oh, and before you start quoting support for Flash, how many Java web developers are really using it? Anecdotally... nobody. Right or wrong, Flash support hardly ranks high on the list of Good Things.
We then turn to Justin's comments:
Ted Neward, a great friend, colleague, and all around smart-guy, just really missed the boat on Rails this last weekend. Dion pretty much hit the nail on the head on the technical response. Rails is a web framework that doesn’t make me think I’m writing a Swing app, or that I’m writing an EJB app. It pretends to be nothing; it is, rather, a powerful framework for writing an app that delivers HTML over HTTP. Hell, what with the ASP.NET/JSF render kit wunderland, I’m starting to wonder if we need a new acronym: POWA (Plain Ol’ Web App). I like the acronym. More, as I said above, I'm heartily in favor of something that will help us "stop the madness" of the "Let's-Hide-The-Web-Part-of-a-Web-App" framework design approach.
Regardless, he also whiffed (sorry big guy) in his musings about managed versions. There is, of course, Trails, a mighty attempt to make the Spring/Hibernate/Etc. stack as easy to configure and use as Rails, and MonoRail, an open source .NET equivalent as well. What fascinates me about MonoRail is that it is one of the first attempts to move away from the standard ASP.NET design pattern; the MVC crowd has just not found a great way to own that space. Maybe MonoRail will be the ticket. (By the way, check out the other stuff going on at CastleProject; DynamicProxy is a great little tool for making synthesized proxies a la Java, without all that Reflection.Emit() hassle.) Won't pretend to know everything, big guy, and more importantly, I didn't want to pretend knowledge of a space that I don't have. Was I reasonably convinced that somebody was already working on one (or more)? Sure, it's not hard to make that assumption. But it's better, IMHO, to take the conservative approach and "let the community tell you", if I may steal-and-paraphrase the XP saying. Now it's time for me to go have a look at those (in my copious spare time) and see if there's any goodness there.
When I say he whiffed, it isn’t because he couldn’t tick off the various projects off the top of his head. Its because he missed that Rails is already influencing everybody else. The “small” feature he mentions, convention over configuration, is catching on like wildfire, and I don’t think it would have unless Rails had highlighted the fact that the 80% case is to only configure 10% of your app. We’re also seeing some folks revise their commitment to web components; with Rails, parameterized partial templates give you most of what you get with web components, and at a fraction of the compexity. This, then, is interesting to me--is Rails only interesting because of "the fact that the 80% case is to only configure 10% of your app"? Or, is it that Rails' sole contribution is that it helps bring the pendulum back away from the layers-upon-layers default approach in Java projects? If that's the case, then I get Rails entirely, and I'll quite happily put the Rails book back on my shelf, because it means that it's major contribution is one of influence, and not one of "need to know for consulting practice". But that's NOT what I'm hearing the Rails-buzzers say, so I'm not convinced that Justin's identified what is is I missed.
Look, guys, at the end of the day, if Rails is about Ruby and the things that a scripting language can do that a compiled, statically-typed language can't, then Rails definitely has a place in the world and I'll take the time to learn it. If Rails is about bringing sanity back to the web framework space, then I'll wait for the Java and .NET Rails-influenced projects to ship and stick with something that has BOTH the sanity AND the support of managed platforms.
So Dion, Justin, if you still think I whiffed, tell me why, pray tell. Or else admit that you're just jumping on a "bright shiny new toy" bandwagon and that two years from now, Rails won't be in anybody's lexicon. In other words, it's "put up or shut up" time. 
|
 Friday, August 12, 2005
|
NFJS Austin, and Rails
|
|
So I'm in the Austin area this weekend, for yet another NFJS show, except this time I actually had time in the schedule to attend the Friday night talks. (Normally I'm too busy traveling to be here on Friday--I typically need the Friday night timeframe to actually get here, which probably explains why my Saturday morning talks are always a crap shoot.)
Part of my reason for wanting to be here early was a desire to see more of Dave Thomas' talks, and in particular, I wanted to get more of the Ruby and Rails Religion that seems to be infesting... er, maybe I should say "spreading like wildfire" instead... my friends in the speaker crowd. I mean, normally they're a pretty sane and sensible bunch, and if these guys are all drinking deeply of the Ruby and Rails Kool-Ade, I want to take a hit from the bong as well and see if it's a good trip, or just a trip.
So I sat through Dave's Rails presentation, and as he was finishing up, I felt strangely disappointed--not so much that Rails isn't a cool little framework, but that there really wasn't anything more there. I mean, I see a bunch of intelligent code-generation and some common-sense defaults, but other than that it's strangely reminiscent of the servlet scene circa 1997--even to the point where Rails will reload modified scripts on-the-fly for you. Hell, if the servlet containers had been smart enough (or crazy enough, depending on your viewpoint) to do the servlet compilation for you on the fly (memory leaks in javac notwithstanding), it would be very much like what we have right now with Rails.
And yet, we didn't stay there in the servlet community once we had that kind of functionality. We found a greater need for configuration, more flexible and powerful execution models, and so on. In essence, as web apps got more complicated, the servlet/JSP space got more complex to match it. "With power, comes complexity; with complexity, comes power." I wonder if Rails will eventually find that same need, or is it always going to target the easiest/easier x% of webapps and leave the harder stuff alone?
In the meantime, am I missing something from Rails? Is there any movement afoot to create a JavaRails ("Jails"? Ew.) project that I'm not aware of? (Come to think of it, in the .NET space too, while we're at it? "Nails", anybody? )
|
 Wednesday, August 10, 2005
|
Starting a new weblog
|
|
With this entry, I inaugurate a new weblog, this one devoted to technical issues of all walks and shapes, including but not limited to Java, .NET, C/C++, and Web services, but with a smattering of Ruby, Python, SQL, and just about anything else that happens to cross my path.
Some may wonder why the separation, considering I already had a weblog that a lot of people were subscribed to. The reasons are pretty simple, when you look at it:
- A vocal, anonymous collection(?) of people complained about the fact that I was talking about .NET issues and people, yet the blog was subscribed to JavaBlogs. While I find it a short-sighted view, I realized that I really should have category support so as to be able to allow readers to "screen out" the postings they didn't want, which brings me to my next reason.
- I'm really tired of my own weblog engine. To put it bluntly, I never really wanted to be in the business of being a blogging provider, yet writing my own engine sort of put me into that space, and I found that, like the proverbial shoemaker's children, I wasn't really spending any energy on bringing it up to speed in feature terms, and, more importantly, I didn't really want to, either. I like writing prose and writing code, but blogging to me was an infrastructure I wanted "to just work", not something I wanted to tinker with. So I decided that I wanted to switch engines.
- I've also found myself periodically hestitating from posting something super-personal (such as a spin on politics or history) because so many had subscribed to my blog for its technical content. Since blogs are supposed to be a personal channel, yet since my blog was clearly also serving as a professional/technical channel, it seemed prudent to split my blogging into a professional channel (here), and a personal one (there). (Actually, I'm going to eventually migrate those entries over to this blog, set up redirects, and do all of my personal blogging from the family blog instead.)
- The blogging engine had served its original intended purpose--to see if Servlet filters could stand in as Controllers instead of servlets in an MVC scenario--and it was time to close the experiment down and let somebody else handle blogging engine featuritis.
In this case, the engine is dasBlog, which has some righteous features that I already love and some of the best technical support in the world. What's more, I'm hoping that the mail-to-weblog and/or the w.Bloggar or Blogjet support will help me blog more often, since I've often found myself on an airplane without an Internet connection and wanting to blog something. In particular, some of the topics I want to blog on in the coming months:
- The Vietnam of Computer Science
- Distributed objects and why "good distributed object model" is a contradiction-in-terms
- Why the term "Web services" should be deprecated in favor of "XML Services" instead
- Weighing in on the duck typing vs. strong typing debate
And a few more, besides. As always, I'm reachable via email, and so long as the comment spam doesn't get too bad, via comments here. Thanks for listening, and here's to many more years of interesting blogging commentary.
|
|