July 2006 - Posts

Xml Axis properties, VB.NET's second cool Xml language construct

Yesterday I posted about the Xml literal support within Visual Basic 9.0 and how it has me envious of VB.NET programmers.  While Xml literals are the most notable language feature available in VB (and not C#) there is one other language construct that is also unique to Visual Basic, Xml axis properties.

The XLinq API provides several core extension methods that developers will use when querying Xml using Linq.  The most notable extension methods are Elements and Attributes.  Elements returns an IEnumerable<XElement> of the child elements within an Xml fragment.  Elements provides an overload that accepts a XName which allows the child elements returned to be limited to those of the relevant XName.  I should note that in most scenarios developers will use a simple string such as “customer” which will be implicitly converted into a XName.  The Attributes method provides the same behavior as Elements except instead of returning an IEnumerable<XElement> it returns an IEnumerable<XAttribute>.

As an example lets pretend we want to write a method that will return all the items within a trimmed down version of Scott Gu’s RSS feed. 

    1 Public Function GetItems() As IEnumerable(Of XElement)

    2     Dim rss As XElement = <rss version="2.0">

    3                             <channel>

    4                               <title>Scott Gu's Blog</title>

    5                               <link>http://weblogs.asp.net/scottgu/</link>

    6                               <description>Scott Guthrie's Blog on ASP.NET and .NET</description>

    7                               <item>

    8                                 <title>Recipe: Dynamic Site Layout and Style Personalization with ASP.NET</title>

    9                                 <link>http://weblogs.asp.net/scottgu/arc...Personalization-with-ASP.NET--.aspx</link>

   10                                 <pubDate>Sun, 23 Jul 2006 02:19:00 GMT</pubDate>

   11                               </item>

   12                               <item>

   13                                 <title>Upcoming Free ASP.NET Team Webcasts -- Live from Redmond</title>

   14                                 <link>http://weblogs.asp.net/scottgu/arc..._2200_Live-from-Redmond_2200_.aspx</link>

   15                                 <pubDate>Sat, 22 Jul 2006 02:15:00 GMT</pubDate>

   16                               </item>

   17                             </channel>

   18                           </rss>

   19 

   20     Return rss.Element("channel").Elements("item")

   21   End Function

After using the Xml literal support within VB 9 to create a trimmed down version of Scott’s feed we use the Element and Elements extension methods to select the data that we’re interested in.  As you can see (line 20) I use the Element() method to select the channel element within the feed and then select all items within the channel element by calling Elements() with a XName of “item”.  As an alternative VB 9 provides axis properties which allow the above to be expressed using a more compact syntax.

   Return rss...<item>

This expressions uses the descendants axis support in VB 9 which can be interpreted as: give me all “item” elements underneath the rss element regardless of where they occur in the heirarchy.  VB9 also has support for child axis’ which can be used to get all elements of a given name directly under a given element.  For example to return all the channel elements underneath the root rss element one could use the following syntax.

   Return rss.<channel>

If your not interested in elements but instead want to get at attributes you can use the attribute axis syntax:

   Return rss.@version 

And finally if you want to grab a particular item you can use the extension indexer to select the item of interest off the resulting sequence like so:

   Return rss...<item>(3)

While Xml literals and axis properties aren’t something that is likely to make or break a programmers language decision it does make working with Xml in VB 9 a “pure joy” ® .  For more information checkout the Xml team’s VB 9.0 Xml Features post and Erik’s Gilad is Right post on lambda the ultimate.

Is the key to building great software ignoring the competition?

A couple of week ago I posted about opinionated software and went as far as saying you might be better off ignoring your users and going with your gut.  Today I think I’ll go a step further and say that I agree with Kathy that we should ignore our competition.

A lot of software that is built today is done so with a feature list that is a mile long.  When building software we often feel that in order to be accepted we have to have every possible feature that our customers, competitors, and every one else in the world may have ever thought of.  Rather then focusing on the core problem we let ourselves get distracted by the latest and greatest feature that was just announced in product X, Y, and Z.  Not everyone can create great software.  If it was as easy as implementing feature after feature over and over we’d have a lot more users with smiles on their faces.  Instead we have overcomplicated software that has too many half done features and not enough simplicity.  As I think about it I think a lot of it comes back to software not being opinionated enough.  It’s a lack of opinion on things that leads to our software getting more and more features.  Rather then having our own opinions we take the opinions of all of our users and we end up with a big mess of features that absolutely positively must be what the users want….afterall its their opinions that we based the whole thing on isn’t it?

In order to create truly great software you need to have opinions on how things should be done.  You need to have a list of things that your product is, as well as a list of things your product is not.  You can’t slap feature upon feature on top of your application and think it will be a success.  Start “ignoring” your competition.  Start “ignoring” your users.  Maybe then you’ll develop your own opinion on what your software is about and create something great.

What do we call the new Xml programming API that ships with Linq?

Soma recently announced the name changing of several Linq related technologies.  As part of the renaming effort XLinq became Linq to Xml.  Although Linq to Xml makes sense as a name for a chunk of the Xml related functionality within Linq it doesn’t fit for everything.  The new lightweight Xml programming API can be used outside the context of Linq and has been left nameless.  Perhaps we should keep calling the Xml Programming API XLinq, and only use Linq to Xml when we’re talking specifically about querying Xml using language integrated query?

XLinq has me wanting to code in VB.NET?!?!

Ever since I started programming in .NET land I’ve been a C# bigot.  The syntax jives with my brain.  When I come across code samples presented in both VB.NET and C# I gloss over the VB.NET code in all it’s verbosity and jump directly to the real code (C#) .

Since the May CTP drop of Linq I’ve been working my way through the various technologies (Standard Query Operators, Lambda Expressions, Expression Trees, Linq to Sql, Linq to Xml, etc) in an attempt to get a feel for what’s available in Linq and what changes it might bring to my daily programming life when I’m able to use it in production applications.

I’ve semi-recently gotten to XLinq and it has me envying VB.NET programmers!  The Xml literal support within VB.NET is pretty sweet.  For those of you who don’t know what I’m talking about the next version of VB.NET has built in support for constructing Xml using literals.  As a quick (also known as “lame”) example imagine that you have a PurchaseOrder class that you need to represent as Xml.  Wtihin VB.NET you can build the Xml representation of the PO using a combination of Xml literals and embedded expressions. The result looks amazingly similar to ASP.NET due to the shared <%=expression%> syntax.

 Public Class PurchaseOrder
   Public PODate As
Date
  
Public Number As
String

  
Public Function AsXml() As XElement
      Return <purchaseOrder><poNumber date=<%= Me.PODate.ToString() %>><%= Me.Number
%></poNumber></purchaseOrder>
  
End
Function
End
Class

* Note: This is the first VB.NET code I’ve written since Beta 1 of .NET

To be fair it should be mentioned that the functional construction of Xml that is provided by XLinq makes creating Xml without xml literals pretty darn nice as well…especially when compared against what we’re used to with existing Xml API’s.

 

The X/O Impedance mismatch

Object Relational Mapping tools  have gotten a lot of “press” over the course of the last several years.  As more and more developers start to realize their potential, they’ll also get to experience the object/relational impedance mismatch first hand!  With the upcoming release of ADO.NET Entities the Microsoft developer community will finally learn to grok the power of the conceptual model.  They’ll learn to love how it lets them think about their domain and they’ll really love the fact that they won’t have to write boat loads of SQL to get the data out of their relational model and into their conceptual domain model.

While it’s receiving a lot less press, XLinq (Linq to Xml) will also bring some very welcome changes for the .NET developers of the world.  XLinq is going to make working with Xml much more natural and much more in line with how we deal with all kinds of data within our applications (Thank you Mr. Linq).  While XLinq will make working with data much more bearable it too will bring to light the impedance mismatch that exists between objects and xml.  Lucky for us it sounds like the brain trust at Microsoft is trying to squash the mismatch out of existence, albeit with quite a few challenges remaining.  In their latest paper Eric Meijer and Ralf Lammel talk in depth about the X/O impedance mismatch (via Sam Gentile).  Although they acknowledge that the X/O impedance mismatch cannot be fully eliminated I’m confident they’ll come as close as possible to making the mismatch disappear.

ADO.NET Entity Framework: How. What. Why.

If your interested in what’s coming in the next version of ADO.NET you’ll want to checkout the ADO.NET Entity Framework: How. What. Why. video on channel 9.  If you’ve already read the ADO.NET Next gen documents on MSDN there isn’t a whole lot in the video that you probably don’t already know.  Hopefully the first CTP will drop soon!

Create a Photo Tagging Site with ASP.NET and Linq

Scott Guthrie's has a nice writeup detailing how he created a Photo Tagging site using ASP.NET 2.0, Linq, and Atlas

Overloading the && and || operators

A couple months ago I posted about our query API along with an explanation of how it works.  Our query API allows us to express our queries using strongly typed C# syntax:

List<Customer> customers = repository.FindAll(Customer.Columns.Age == 20 & Customer.Columns.Name == “foo”);

One of the things I pointed out in my previous posts was that I couldn’t overload the && and || operators directly since the framework doesn’t allow such craziness…at least not directly.

In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ?:, checked, unchecked, new, typeof, as, and is operators.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_7_2_2.asp

Over the last month I’ve done a little investigation on the topic to see if and how I can get && and || to behave the way I want.  This evening I came across the Conditional logical operators page on MSDN which gave me the answer I was looking for:

  • The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Then, if x is definitely false, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
  • The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x, y) is an invocation of the selected operator |. In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. Then, if x is definitely true, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.

Since we already have the & and | operators in place it was simply a matter of overloading the true and false operators to both return false.  This results in the & and | operators always being called which in turn results in the two criteria objects being turned into an AndCriteria/OrCriteria! 

So now we can express our criteria expressions using the && and || syntax we’re accustomed to.

repository.FindAll(Customer.Columns.Age == 20 && Customer.Columns.Name == “foo”);

repository.FindAll(Customer.Columns.FirstName == “Foo” || Customer.Columns.LastName == “Bar”);

The relevant operator overloads are shown below.

public static bool operator true(Criteria<T> criteria) {
  
return false;
}

public static bool operator false(Criteria<T> criteria) {
  
return false;
}

public static Criteria<T> operator &(Criteria<T> lhs, Criteria<T> rhs) {
  
return new AndCriteria<T>(lhs, rhs);
}

public static Criteria<T> operator |(Criteria<T> lhs, Criteria<T> rhs) {
  
return new OrCriteria<T>(lhs, rhs);
}

Rails is...Opinionated Software

About 6 months ago I was on a pretty big Rails kick.  I read lots of articles on Rails, got the Rails book, and installed all the bits necessary for running Rails on my PC and Mac.  Since that time I’ve kept myself pretty busy with work related things as well as the obvious research into Linq, and ADO.NET Entities.

While my focus on Rails has gone by the wayside I’m still a big fan.  Tonight as I was working in .NET land I fired up DHH’s RailsConf 2006 Keynote.  As I was semi-listening to him I kept hearing a lot of the same themes that I read over and over again back when I was learning about Rails.  DHH is all about opinionated software.  Hist strong opinions are what makes Rails successful.  DHH embraces constraints, keeps things simple, and does things his way…and he does so with amazing success. 

One of the biggest mistakes that framework developers make is trying to satisfy everyone and everything.  They get swayed by the users of their framework and end up compromising the simplicity of their framework for all the latest wizz-bang features that the community demands.  Simply put they don’t have strong enough opinions on how things should be done.  Rails has no such problems. 

Is your software opinionated enough?

Scrummerfall

Scrummerfall. n. The practice of combining Scrum and Waterfall so as to ensure failure at a much faster rate than you had with Waterfall alone.

Successful agile projects require far more discipline than any other methodology I've ever used. Doing XP right, all the time, is very hard work.

Brad Wilson

Are you doing Scrummerfall?  Are you having success?

Stongly Typed Reflection with Linq

Daniel Cazzulino has an interesting post on how upcoming C# 3.0 features can be used to provide a strongly typed reflection API

Other Linq Stuff: