donderdag 5 mei 2011

Ugly lambdas in VB.NET

When I was 14 years old my sister bought me a gift for my Christmas.  It was called Dark Basic.  It promised the user to make games in a jiffy without any hardcore programming knowledge.  To my disappointment when I started the application all I got was a blank black screen with a white blinking cursor. 
I was a bit confused at that point, since I imaged some kind of drag and drop mechanism and some cool monsters and half naked woman I could select.  Nopes, that wasn’t it.  Instead it was a BASIC language which allowed the user to easily write 3D games without having to think about low level transformations.  After a couple of days, I started to get the hang of it and it was very addictive. 

Why am I telling you this?  Well just to show you that I have no grudge what so ever against BASIC languages.  I know DarkBasic, Visual Basic 6, VB.NET and I even experimented with QuickBasic, so I think I’ve had my share of experience with BASIC languages. 
Now the last 6 months, I’ve been working in VB.NET again (yes they putted a gun against my head and kidnapped my girlfriend).  And I can say to you that once you’ve got a taste of C#, it’s a bummer to go back to Visual Basic.  My biggest issue with VB.NET is Lambdas.  No matter how hard you try, there is just no way you can make this look pretty.  ‘So than just don’t use them’ I hear some VB.NET fans yelling while putting on an ice pack on their sore fingers from all the typing they did today.  Well in some situation, I believe the lack of lambdas will spaghetify your code.

Imagine we want to use the MVVM pattern in Silverlight and we are writing some RelayCommand.  In C# we can just write:

public RelayCommand GettingJiggyWithIt
{
      get
         {
          return new RelayCommand(() =>
                                       {
                                          var me = GettingJiggy();
                                          WhoIsGettingJiggy = me + WithIt();
                                        });
         }
}

While in VB.NET we either inline it with the most ugliest and unclear syntax I’ve seen in my life or we can make it jump to a method defined elsewhere:

    Public ReadOnly Property GettingJiggyWithIt As RelayCommand
        Get
            Return New RelayCommand(Sub()
                                        Dim I = GettingJiggy()
                                        WhoIsGettingJiggy = I + WithIt()
                                    End Sub)
        End Get
    End Property

Sure this example isn’t such a PIA but then Imagine we want to start testing. Using MOQ or RhinoMock we want to create some mocks in our test.  While using C# we can do this:

mockDal.Setup(dal => dal.GetPersonsRoles).Returns(new Person { Name = "Maria" })

Just gorgeous.
While in VB.NET we are obligated to do this:

mockDal.Setup(Function(dal) dal.GetPersonsRoles).Returns(New Person With {.Name = "Maria"})

So I guess I’m still a bit whining as this example doesn’t look THAT bad.  Sure, now Image you want to do the same thing MOQ described on their QuickStart guide:

mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>();
 

public string IsLarge()
{
  return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100);
}
 
In VB.NET this would become:
mock.Setup(Function(foo) foo.Submit(IsLarge())).Throws(Of ArgumentException)()
 
Public Function IsLarge() As String
        Return Match(Of String).Create(Function(s) Not [String].IsNullOrEmpty(s) AndAlso s.Length > 100)
End Function

The syntax is so ugly, the spellings and grammar processor of Words just crashed (seriously).
So what can we do to make this look a bit nicer?  Using the AddressOf operator will just turn your code into spaghetti.  One solution I came up with was to declare each lambda separately and then use it in one fluent sentence. Like this:

Dim whenSubmitingToLarge = Function(foo) foo.Submit(IsLarge())
mock.Setup(whenSubmitingToLarge).Throws(Of ArgumentException)()
 
It still isn’t pretty, but it is prettier in my opinion.  Still, if you have the choice to choose between VB.NET or C# then choose C# without a doubt.  Lambdas are just one of the many ugly constructs VB.NET holds itself to.  Some other syntactical catastrophes’ I can think of are attributes, extension methods and so on.

I needed to get that off my chest, until next post ;)

Geen opmerkingen:

Een reactie posten