Ruby 1.8 vs LINQ
Jon Udell: I’ve been checking out the LINQ technical preview, and it’s definitely an eye-opener. The following snippet does a three-way join across an XML data source and two CLR objects. The XML data source is the content of this blog. The objects are a dictionary of date mappings, and an array of strings. The output is constructed as XML.
As an educational exercise, I’ve converted this to Ruby
doc = REXML::Document.new open("blog.xml") d = {"2005/09"=>"September 2005", "2005/08"=>"August 2005"} a = ["greasemonkey", "ajax"] xml = Builder::XmlMarkup.new REXML::XPath.match(doc,"//item").select {|item| d.keys.find {|key| item.elements["date"].text.include? key} and a.find {|tag| item.elements["tags"].text.include? tag} }.sort_by {|item| item.elements["date"].text}.reverse.each {|item| xml.item { xml.month d[d.keys.find {|key| item.elements["date"].text.include? key}] xml.date item.elements["date"].text xml.title item.elements["title"].text xml.tags item.elements["tags"].text } } puts xml.to_s
Things to note:
- From a functionality point of view, the two implementations are largely equivalent (though some differences are mentioned below). This means that the differences are primarily syntax. In fact, the impression I got from this video is that C#'s LINQ support is largely syntactic sugar over roughly equivalent runtime functionality. That being said, syntax matters. Very much so. And having an SQL like syntax is a big enabler for many folks.
- Note I said “SQL like”. What in reality you
have is SQL#. In Jon’s example, I see
&&
andsortby
. In other examples, I have seen==
. Not to mention the Yoda-like “from, where, select” . More importantly, in both Jon and my examples you are very much aware of the data sources, with things likeDescendants
andElement
sprinkled throughout the code. - Despite progress being made with
var
declarations, the C# implementation still requires the developer to be more involved with the data typing administrivia than the Ruby one does. In particular, note the(string)
in the middle of the query. - Conversely, the Ruby implementation, the developer is more
involved in the administrative details associated with naming In
particular, note the three occurrences of
|item|
and in building the XML, I had to say that one needs to get “tags” and call the resulting XML element “tags”. The latter could be improved with better integration between Ruby’s XML builder and REXML. - The biggest functional difference is that I had to write the code to find the month twice. LINQ’s implementation could do the same, or it could add an additional map step. While not a big deal in this particular example, it could very well be a significant issue in larger examples.
All in all, a little competition in language design is a good thing. Ruby would do well to study LINQ. And, of course, Perl 6 (if it ever ships) would allow third parties to design such syntaxes for themselves.