Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Sergio Pereira

There are no half-solutions because there isn't half a problem

May 2008 - Posts

  • The Fluent Interfaces or DSLs Conundrum

    Maybe I'm just behind the curve on this one, but I don't understand the fascination with building internal DSLs (or the so-called fluent APIs) in C#. The argument is usually that they are expressive and readable but, since these are subjective assessments, I happen to disagree on both counts. They would need to bring some other values to the table to convince me to use them without being annoyed.

    I think C# is not well suited for this task and maybe we should just stop trying to imitate what we see in other languages.

    The idea that we can create classes named Is or Returns or With just rubs me the wrong way. At the present moment I hope this trend is just a fad. I'm willing to be proven wrong and suddenly "get it." Time will tell.

    Take the following snippet using Rhino Mocks.

    With.Mocks(mocks).Expecting(() =>
    {
        Expect
    	.Call(dependency.GetSomething("p1"))
    	.IgnoreArguments()      
    	.Repeat      
    	.Once() 
    	.Return("result");
        dependency.DoSomething();
    })

    Imagine yourself trying to setup this expectations. You know that when calling dependency.GetSomething("parameter") it should return "result". How would you discover that the With class is your starting point? Then look at the lambda code. I'd imagine your first reaction would be to look for a method in Expect that would take both the method call and the result. I'd say your first reaction is appropriate, after all this is still supposed to be C# code.

    Maybe the desire behind these fluent interfaces is to make the API have a little more keyword wannabes at the expense of tolerating all the punctuation and ceremony that comes along.

    In other languages this type of APIs are more popular because the language lends itself more adequately to this design. I'm not an Objective-C programmer but take a look at this line.

    [expect call:[dependency getSomething:@"p1"] repeat:1 returns:@"result"];

    Or in Ruby, probably leveraging the method_missing goodness behind the scenes:

    dependency.expectCall.getSomething("p1", 
    	:ignore_arguments => true, 
    	:repeat => :once,
    	:returns => "result"
    	)

    For a Objective-C or Ruby developer the above translations probably read more natural than the C# version for a C# developer.

    I'm using Rhino Mocks as an example because it is fairly popular. I'm not trying to pick on it. Just to give another example of a fluent interface, recent versions of NUnit come with the Constraint Model for assertions:

    Assert.That( ex3, Is.Not.SameAs( ex1 ) );

    Again, classes, properties, and methods being used as quasi-operators, trying to blur the lines between language features and the custom API. But C# fights back and makes clear that it is not open for these kinds of extensions and throws a bunch of punctuation at you. To me this just doesn't feel fluent. It doesn't read like English nor like C#. It's more like some schizophrenic middle-of-the-road compromise.

    It's possible that this desire to write fluent interfaces and DSLs becomes just a gateway to a more appropriate language like IronRuby or even Boo (to stay in the .Net universe.) Or, who knows, maybe C# changes to be more friendly to these designs. I will not be surprised if, in a few years, we look back at all these implementations and feel a little embarrassed for trying so hard to recreate an experience that is just not viable. Equally, I will not be surprised if I'm proved wrong, jump on the bandwagon, and regret having ever written this piece.

  • And the winner is... VB.NET ?!

    Every time I see an updated version of the TIOBE index it strikes me differently. Sometimes I'm surprised to see some programming languages in the TOP 20 that I didn't even know existed (happens all the time,) sometimes it's the realization of the languages on the rise like Ruby and Lua in recent years.

    Take a look at this month's list.

    1 Java 20.176%
     
    2 C 15.292%
     
    3 (Visual) Basic 10.782%
     
    4 PHP 10.637%
     
    5 C++ 10.484%
     
    6 Perl 5.869%
     
    7 Python 4.613%
     
    8 C# 3.963%
     
    9 Ruby 2.851%
     
    10 Delphi 2.641%
     
    11 JavaScript 2.411%
     
    12 D 1.314%
     
    13 SAS 0.738%
     
    14 PL/SQL 0.625%
     
    15 Pascal 0.498%
     
    16 Lisp/Scheme 0.449%
     
    17 Ada 0.431%
     
    18 COBOL 0.411%
     
    19 Lua 0.393%
     
    20 FoxPro/xBase 0.385%
     

    This month, although not new, what hit me was the state of the .Net languages. I'm definitely a C# guy. You'd have to tempt me with serious money to get me doing VB.Net again (IronRuby, on the other hand, would be a different story ;)

    Although I'm not exactly surprised to see the .Net languages being dwarfed by other heavy hitters like Java and C, which enjoy a little more platform-independence, it's always an humbling effect seeing VB that far ahead of C#.

    The interesting thing with this index is how it is built. It serves as a good thermometer to what kind of support you can expect to find on the Internet for that language. That's why it surprises me in relation to Visual Basic in particular.

    I understand the index lumps together VB.NET, VB6, plain Basic, etc, but the non-Net versions of VB have been considered legacy for so long now that I tend to think VB.NET is indeed what is pushing Visual Basic to the top.

    Maybe it's just because "Visual Basic" or "VB" as much easier search terms than "C#", "CSharp", "C-sharp", etc.

    I've been reading about .Net online for almost 8 years now and C# has always seemed more prevalent than VB.NET in article, samples, documentation, and Open Source projects.

    What about you? Anything interesting in this list? Is VB really the bomb?

  • Chicago ALT.NET - May 08 meeting summary

    Last night we had the monthly meeting of the Chicago ALT.NET group. After a few social/networking and group planning events, this was our first content-bearing event.

    We had the pleasure of having Dan Sniderman come and talk about his experience with TFS and how we can build a Continuous Integration process with it. Dan talked about the different components and options in TFS and it was a very useful presentation, especially for me, because I'm going through the process of making CI a fundamental part of my client's workflow.

    The discussion was not limited to TFS as it was constantly put in perspective against the other non-MS CI offerings. Knowing what TFS can do in comparison to the existing alternatives like SVN, TeamCity, CruiseControl.net, trac, JIRA, etc will enable me to assist the client choosing the most appropriate option for their team and infrastructure.

    I'm very happy with the level of the discussions and knowledge sharing that we got in that meeting. It was not your average user group lecture. I think that is the direction we want our group to follow, not limiting our scope to MS branded products and eventually looking outside of the .Net boundaries as well.

    Topics for our future meetings are up for voting, but it looks like we will soon be talking about NHibernate, IoC containers, distributed architectures, TDD, ORMs, rich JavaScript client libraries, etc.

    If you want to learn more about the group and attend future meetings, check out our mailing list and our calendar (iCal).

  • Interview for the Prototype blog

    Recently, Tobie Langel from the Prototype blog asked me to answer a few questions about Prototype.js and my involvement with it.

    The interview has been posted today. The folks in the Prototype team have been producing some wicked cool code for a while and they're working on a number of interesting things to enrich the developer experience. I'd advise you to keep an eye on that blog for constant innovation in the JavaScript sphere.

  • JavaScript: The Good Parts - book review

    I just finished reading Douglas Crockford's JavaScript: The Good Parts and it only took me a few hours to go through it this weekend. This is a short and delightful read. The book has not been released in print yet and I read it via O'Reilly's Safari Bookshelf, which will be the subject of a future post by itself.

    Update: The book became available almost at the same time I posted this review.

    In its 170 pages the book describes not only the HOWs but, most importantly, the WHYs of the JavaScript language. Douglas Crockford is known for his great contributions for JavaScript development, including JSON, JSLint. JSMin, and several programming patterns and practices.

    In this book, Douglas explains JavaScript and how it differs from other popular object oriented programming language. Special attention is given to JavaScript's inheritance model and scoping rules.

    Crockford doesn't limit the coverage to what is considered good in the language design. He also sticks his finger at the problems in the language and what he considers (justifiably) bad language design and missing features. A lot of attention is also given to common sources of bugs and how to avoid them.

    This is such an easy and valuable read that I have to recommend it to anyone trying to produce solid and maintainable JavaScript code.

  • Designing With Lambdas - Part IV

    My previous posts in this series revolved around using lambdas to encapsulate logic. In this post I'll show a different side of the lambdas, the expressions.

    Lambda Expressions

    We have already seen that lambdas can be used to create anonymous methods to be passed wherever a delegate is expected. That's not the end of the story, though.

    Lambdas can also be used where an Expression<DelegateType> is expected. The difference is that the compiler will not resolve the lambda to an anonymous method. Instead the lambda will be converted to an expression tree, which is a way to describe the code in the lambda.

    If you used LINQ to SQL for example, you have already been using lambdas that are converted to expressions. Expressions are what enable LINQ to SQL to convert a LINQ query like this:

    from cust in Customers
      where cust.City == "London" 
      && cust.ContactTitle == "Sales Representative"
      select cust
    into a SQL query like this:
    SELECT 
    	[t0].[CustomerID], [t0].[CompanyName], 
    	[t0].[ContactName], [t0].[ContactTitle], 
    	[t0].[Address], [t0].[City], [t0].[Region], 
    	[t0].[PostalCode], [t0].[Country], 
    	[t0].[Phone], [t0].[Fax]
    FROM [Customers] AS [t0]
    WHERE 
    	([t0].[City] = "London") 
    	AND ([t0].[ContactTitle] = "Sales Representative")

    In particular, pay attention to how the where clause was converted from C# syntax to SQL syntax.

    Yet another JSON converter

    Let's illustrate how expressions can be used by creating some code to convert objects to JSON.

    What I will try to produce here is a converter that let's me specify which properties of my object will be included in the JSON version of the object.

    One way to accomplish this could be by simply passing a list of property names to a conversion function that would work some reflection magic and extract the properties into the JSON format.

    string userJson = ConvertToJson(userObj, "Name", "Email", "Age");

    The biggest problem here, in my opinion, is not the reflection activity behind the scene, it's those strings. If you change the name of any of the properties the compiler and the refactoring tools won't be able to help you updating those strings. You may end up with runtime errors.

    With lambdas and expressions we can do better. Here's the syntax that I will build.

    class Company               
    {                   
    	public string Name { get; set; }      
    	public int CompanyID { get; set; }      
    	public string Address { get; set; }     
    	public bool PlatinumCustomer { get; set; }    
    	public string InternalControlNumber { get; set; } 
    }          
    
    // object that we will convert
    var acme = new Company {        
    	Name = "ACME, Inc." ,       
    	InternalControlNumber = "3X77-AC",  
    	Address = "123 Main St, Anytown, ST", 
    	PlatinumCustomer = true,      
    	CompanyID = 789         
    };                
    
    //convert it but only copy a few properties
    string json = ConvertToJson<Company>(acme,  
    	c => c.Name,        
    	c => c.CompanyID,     
    	c => c.PlatinumCustomer);

    The resulting JSON string, stored in the json variable will be:

    {"Name":"ACME, Inc.", "CompanyID":789, "PlatinumCustomer":true}

    Each of the lambdas passed in contain just one access to an existing property. As soon as you start typing this you'll already see the advantage of working with strongly-typed constructs like this. IntelliSense will automatically list the Company properties and methods once you type c.. Also, if you rename one of the properties, the IDE will offer to rename all references to that property, and the lambda will also be included in the renaming. Lastly, your code won't even compile if you make a typo.

    The code for ConvertToJson will receive an array of expressions of type Expression<Func<T, object>>. This type looks complicated but if we think about it from the inside out, Func<T, object> is something you typically see in regular lambdas. It's a delegate type. As soon as we decorate that delegate type with an Expression< T > around it, the compiler will continue to accept the lambda syntax for anonymous methods but now the method never gets invoked, it will become an expression tree, which is then passed to the function. Here's the function.

    public static string ConvertToJson<T>(                 
    	T data,                            
    	params Expression<Func<T, object>>[] properties)         
    {                                
    	int exportedFields = 0;                      
    	StringBuilder json = new StringBuilder();                
    	json.Append("{");                        
    	foreach(var prop in properties)                    
    	{                                                  
    		string propName = null;                    
    		object propVal = null;                   
                                     
    		if(prop.Body.NodeType == ExpressionType.MemberAccess)          
    		{                          
    			PropertyInfo pi = 
    				(PropertyInfo)((MemberExpression)prop.Body).Member;  
    			propVal = pi.GetValue(data, null);             
    			propName = pi.Name;                  
    		}                          
    		else if(prop.Body.NodeType == ExpressionType.Convert)          
    		{                          
    			UnaryExpression expr = (UnaryExpression)prop.Body;       
    			PropertyInfo pi = 
    				(PropertyInfo)((MemberExpression)expr.Operand).Member;
    			propVal = pi.GetValue(data, null);             
    			propName = pi.Name;                  
    		}                          
    		                           
    		if(propName != null)                     
    		{                          
    			string stringVal = null;                 
    			if(propVal == null) stringVal = "null";            
    			else if(propVal is string) stringVal = "\"" + propVal + "\"";    
    			else if(propVal is bool ||               
    				propVal is byte ||               
    				propVal is int ||                
    				propVal is long ||               
    				propVal is short)                
    					stringVal = propVal.ToString().ToLower();  
                                     
    			if(exportedFields > 0) json.Append(", ");         
    			json.AppendFormat(@"""{0}"":{1}", propName, stringVal);      
    			exportedFields++;                  
    		}                          
    	}                              
                                     
    	json.Append("}");                        
    	return json.ToString();                      
    }

    The above code is just for illustration purposes. It does not handle (for example) properties that are other complex objects. A more complete version can be written but it could get very long and beyond the scope of this particular example.

    In the code we can see that the function receives the object to be converted and also an array of expressions. Each expression describes a function that accepts a parameter of type T (Company in our sample) and returns an object. Expressions ca get very complex but we are simplifying our life by only accepting one-liners that call one of the object's property.

    With each expressions we inspect them to see if we can find the part that mentions the property information, we get its name, and then we get the property value. After some trivial formatting of the value, we add the name/value pair to the JSON result.

    How to choose Expressions over Delegates

    The key is the execution or not of the lambda. If the lambda will eventually be invoked, which I'd argue will be the majority of the cases, then you need a simple delegate. When what you need is a way to represent a structure or data item that has an appropriate version in code (like our properties or the table columns in the LINQ to SQL example,) and maybe later you need to transform the code version in some other form, or use it somewhat like configuration, then you're probably looking at an opportunity to employ expression trees.

  • Unescape my Strings

    Since I started using Visual Studio 2005 and now 2008 it bugs me that strings in the debug windows (Immediate, Watch, Locals, Autos, etc) are automatically escaped in C# syntax (well, at least in C# projects.)

    Let's assume we are writing some code that produces HTML (or XML, or SQL, or JSON, etc) where the text identation is important for understanding the contents. If we find ourselves in the middle of debugging that code and check the value of a variable containing such type of text, here's what we would see.

    System.Diagnostics.Debug.WriteLine(html);
    Console.WriteLine(html); // BREAKPOINT HERE
    Console.ReadLine();

    The Immediate window becomes less useful. The line breaks below do not exist in the Immediate window, I added them here for clarity.

    ?html
    "<html>\r\n\t<head>\r\n\t\t<title>Monthly Report</title>\r\n\t\t<style>
    \r\n\t\t\t.results td {color:#999;}\r\n\t\t\t/*etc*/\r\n\t\t</style>\r
    \n\t</head>\r\n\t<body>\r\n\t\t<h1>Report for April 2008</h1>\r\n\t\t<d
    iv id=\"content\">\r\n\t\t\t<p>\r\n\t\t\t\ttext goes here...\r\n\t\t\t<p
    >\r\n\t\t</div>\r\n\t</body>\r\n</html>"

    Same problem in the Locals or Autos windows, but there at least you can use the visualizers.

    Too many clicks for me, though. Besides, the visualizers are modal windows and that makes it harder when you want to compare things.

    If you happen to know how to revert to the old behavior of keeping the text format, please let me know. Until I find the right way (or at least a better way) I'm using a little macro to output any selected escaped text, unescaped to a new output pane.

    To create the macro:

    • View » Other Windows » Macro Explorer
    • Right-click "My Macros" » New Module
    • Call the new module Unescape
    • Add the following sub
    Public Module Unescape
      Public Sub UnescapeText()
        Dim winName As String = "Unescaped"
        Dim win As Window
        Dim output As OutputWindow
        Dim pane As OutputWindowPane = Nothing
    
        If DTE.ActiveWindow IsNot Nothing AndAlso _
          DTE.ActiveWindow.Selection IsNot Nothing Then
    
          Dim text As String = DTE.ActiveWindow.Selection.Text
    
          If Not String.IsNullOrEmpty(text) Then
    
            text = text.Replace("\t", vbTab) _
              .Replace("\r\n", vbCrLf) _
              .Replace("\n", vbCrLf) _
              .Replace("\r", vbCrLf) _
              .Replace("\""", """")
    
            win = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
            output = win.Object
    
            For Each p As OutputWindowPane In output.OutputWindowPanes
              If p.Name = winName Then
                pane = p
                Exit For
              End If
            Next
            If pane Is Nothing Then _
              pane = output.OutputWindowPanes.Add(winName)
    
            win.Activate()
            pane.Activate()
            pane.OutputString(text)
          End If
        End If
      End Sub
    End Module

    I made a shortcul for this macro:

    • Tools » Options » Environment » Keyboard
    • Show commands containing: unescape
    • Select the macro when it gets listed
    • Add a Global shortcut, I used Ctrl+Alt+U

    Now if I select the escaped text in the Immediate window and press the macro shortcut, I get the following:

    If I keep selecting other escaped texts and unescaping them, they'll just be appended to that output, making it possible to do some visual inspection or comparisons.

  • Give JavaScript a chance

    Let me be the first one to admit taking way too much time to give in and embrace JavaScript. This language is arguably one of the most widely deployed and most misunderstood at the same time. There must be an award somewhere for this amazing feat.

    I don't know what causes developers to avoid JavaScript in this day and age. I mean, back in 1995 when it was being introduced, I could understand the disdain. Back then it was a new language with a poorly chosen name (no, ECMAScript doesn't help either) and, probably the biggest problem, a lot of pain associated with the bug-laden and incompatible browser implementations of both JavaScript and the DOM.

    Today, on the other hand, I don't see a really justifiable reason for a web developer avoid writing rich JavaScript. We have a very viable install base of browsers with decent implementations of JavaScript and the DOM (not perfect nor uniform, but doable,) we have better development tools, incredible browser extensions, debuggers, unit testing helpers, documentation generators, and, what in my opinion made JavaScript a true professional language: great libraries.

    My hat goes off to Prototype.js, Scriptaculous, jQuery, Dojo, YUI, ASP.NET Ajax, etc. The folks behind these libraries really helped JavaScript adoption and boosted developer productivity. They pushed the language to its limits and amazed us with what could be accomplished with a language we used to simply copy, paste, adjust, and pray it worked.

    I read this somewhere that I can't remember now, but it's a perfect analogy: You wouldn't write .Net code without the BCL, so why write JavaScript without good libraries?

    I see a lot of effort being put into, once again, taking JavaScript away from the developer's code editor, and I honestly don't like that.

    Things like GWT, Volta (me too, me too), Script#, and RJS (plus helpers) sound like too much work only to not let developers use JavaScript directly. Why do I need a to write code in one language just to produce code in another language that is perfectly usable? JavaScript is not Assembly, MSIL, or Java byte-code. We can actually write, document, test, debug, version, and deploy JavaScript.

    I don't know what is your reason not to use JavaScript but maybe it falls into one of the following categories.

    • You think JavaScript is hard: It's not, I swear. Think about this for a second, JavaScript is considerably smaller than C#/Java/Ruby/VB. Maybe the problem you have is that you are being fooled by the curly braces and thinking JavaScript relates to C or Java or C#. JavaScript only has superficial similarities with those languages. The best advice I can give is to get yourself a good JavaScript book. There aren't many good books but I'll leave links for a couple at the end.
    • It's a lot of effort to get anything done: Just pick a JavaScript library and play with it. There's a wealth of solid solutions and widgets for all sorts of things.
    • I like to write all my code in C# (or VB, or Java, etc) I don't want to get into the debate about polyglot programming in this post but afraid you're setting yourself up for grief and failure. You don't want to ride your mountain-bike in the sand dunes or drive our sedan on the train tracks.
    • But my users can turn off JavaScript in their browsers: That never stopped people from writing VC++/MFC, Java, .Net, or even VB6 applications. You'll have the same problem if you're letting your JavaScript be generated on your behalf.

    If you think you need to brush up you JavaScript but don't have a lot of time right now, I'd recommend at least watching the videos linked below.

    Links

    Libraries

    Books

    Tools

    Videos

More Posts

Our Sponsors

Red-Gate!

Proudly Partnered With