2D Head with a clock as an eyeball.
 Thursday, October 16, 2008

Jason recently produced this post where he demonstrates some lambda expression tree parsing and extension methods in C# 3.0 to do windows forms data binding sans strings:

nameTextBox.Bind(t => t.Text, aBindingSource, (Customer c) => c.FirstName);

I happen to like the idea so much that I thought about how this might look in F#. There are some juicy language features in F# sharp that lap this stuff up. Take Jason's C# implementation:

public static class ControlExtensions

    public static Binding Bind<TControl, TDataSourceItem>
        (this TControl control,  
        Expression<Func<TControl, object>> controlProperty, 
        object dataSource,  
        Expression<Func<TDataSourceItem, object>> dataSourceProperty) where TControl: Control
    { 
        return control.DataBindings.Add( 
            PropertyName.For(controlProperty),  
            dataSource,  
            PropertyName.For(dataSourceProperty)); 
    } 


public static class PropertyName

    public static string For<T>(Expression<Func<T, object>> property)
    { 
        var member = property.Body as MemberExpression; 
        if (null == member)
        { 
            var unary = property.Body as UnaryExpression; 
            if (null != unary) member = unary.Operand as MemberExpression;
        } 
        return null != member ? member.Member.Name : string.Empty; 
    } 
}

While this gets the job done, the fact that every last type needs explicit declaration gets in the way of some otherwise damn elegant thinking. The signature for the Bind extension is crazy long, and the phrase "angle bracket tax" comes to mind.

What if our compiler would infer these types for us while preserving compile time type checking? I still want to provide some generic type constraints but beyond that, I don't care.  Using F# we can have these all of these things to give us readable solutions to difficult problems. Also note the extension method syntax:

#light 

open System.Windows.Forms
     
type Control with 
    member this.Bind (control_property : #Control->'b) datasource datasource_property = 
        this.DataBindings.Add(
            property_name_for control_property,  
            datasource,  
            property_name_for datasource_property 
        ) |> ignore

I've deliberately left the implementation to property_name_for till now because it uses some little known constructs. Quotations in F# allow the developer to inform the compiler that a particular piece of code is to be dealt with as an expression tree. To quote code we use the <@ expression @> construct. Being a functional language (amongst other paradigms) F# also allows us to pass lambdas around as variables and parameters unevaluated without any ceremony, thus yielding a readable approach to finding the name of a property in a lambda expression body:

#light 

open Microsoft.FSharp.Quotations.Patterns
     
let property_name_for (p:'x->'y) =  
    let rec parse_expression e =
        match e with 
        | Lambda(var, body) -> parse_expression body 
        | Let(var, lhs, rhs) -> parse_expression rhs 
        | PropGet(opt, info,  expr) -> info.Name 
        | _ -> "" 
    parse_expression <@ p @>

Note the usage of active patterns Lambda, Let &  PropGet provided by the latest CTP of F# in Microsoft.FSharp.Quotations.Patterns we can analyse the expression p to recursively hunt property gets in the lambda body. The Quotations.Expr class conversely, allows us to construct these patterns. The latest CTP has simplified the Quotations namespace dramatically and now utilizes the standard .NET reflection libraries consistently. The list of patterns and constructors is extensive so rather than going through them all here, here's the link to the docs.

Full listing with example usage:

#light 

open System.Windows.Forms
open Microsoft.FSharp.Quotations.Patterns
     
let property_name_for (p:'x->'y) =  
    let rec parse_expression e =
        match e with 
        | Lambda(var, body) -> parse_expression body 
        | Let(var, lhs, rhs) -> parse_expression rhs 
        | PropGet(opt, info,  expr) -> info.Name 
        | _ -> "" 
    parse_expression <@ p @> 
       
type Control with 
    member this.Bind (control_property : #Control->'b) datasource datasource_property = 
        this.DataBindings.Add(
            property_name_for control_property,  
            datasource,  
            property_name_for datasource_property 
        ) |> ignore 

(* EXAMPLE ONLY *) 
type Customer = { 
    FirstName   : string
    Age         : int
} 
             
let nameTextBox = new TextBox()
let ageSelect = new NumericUpDown()
let bs = new BindingSource()
bs.DataSource <- { FirstName = "Jim"; Age = 29 }

nameTextBox.Bind (fun ctrl -> ctrl.Text) bs (fun c -> c.FirstName) 
ageSelect.Bind (fun ctrl -> ctrl.Text) bs (fun c -> c.Age)

Filed under:
 Wednesday, October 01, 2008

Is TDD over the top? Surely can I write my tests 'alongside' my code?

Short answer: No.

Long answer:

To borrow Michael Feathers, author of "Working effectively with Legacy Code" the definition of legacy code is code without tests. By writing a function without a test first, you've just banged out a whole bunch of legacy code. It might not feel like it, but you could have just wasted your precious time.

OK, so lets pretend we have some of this legacy code in front of us. We begin writing some tests to cover it. What you'll find is that many programmers do one of a few things:

  • Coder A will write four or five tests for every method and generally not have to change their implementation much, if at all.
  • Coder B writes less tests overall, but in order to get it there they had to change their code due to recognising some unnecessary coupling or logic.

The next few examples are people who would have used TDD or no tests at all...

  • Coder C used TDD but strangely the end result looks like Coder A's code.
  • Coder D thinks unit testing is a waste of time, and has already deployed to production by now and is currently smugly sipping on Kool Aid.
  • Coder E only wrote a few tests, each test concerned with what the code should do, not what the code currently does, or how it goes about doing it.

Now that we have brutally put everybody in a box with rash generalizations and assumptions, lets come up with a way to throw a cat amongst the pigeons. Generally the best way to do this to a developer, is to ask them to add a new feature to their code.

  • Coder A when finished, finds that all the old tests wont even compile let alone pass because the new requirements severely altered the required architecture. Time is wasted rewriting all the tests to facilitate the new architectural requirements.
  • Coder B finds that only half of the old tests build or pass after implementing the new code. Because they removed some coupling it was easy enough to add, but they wasted time on some old tests that were obsolesced by the new architecture.
  • Coder C decides that the existing test suite isn't going to facilitate the new requirements. After they rewrite most of their tests they rewrite the code to satisfy them. Its like much Coder A's experience just in reverse.
  • Coder D deploys the new code to production or QA, only to find that the new changes stomped all over old functionality. What do you mean it 'doesn't work'? That's impossible! Time for a week long debugging session.
  • Coder E on the other hand writes one more test to the test suite and adds as little code as necessary to make it pass, then brutally refactors anything possible. None of the tests needed rewriting in the process. All user requirements are met and the project is delivered on time and on budget. If your lucky that is...

What some people fail to understand, is that using TDD doesn't prevent you from writing bad code. On the contrary, it can encourage you to over specify things. When you over specify, you increase the places in your test suite that depend on how your implementation is structured. The very same thing happens when you write a function, and then a test or write tests 'alongside' your code. This is the mistake that Coder C makes, taking the bull by the tail, instead of the horns.

Coder E has no idea that he/she is in part practicing BDD. Its a natural progression from blindly banging out tests to cover every feasible outcome. Eventually you get a feel for tests that give you maximum 'bang for buck'. These tests provide maximum (quality) coverage for the least effort. In other words, we aren't bothering with a test per function. We are writing one test per desired behaviour.

OK so every now and again, you head down the wrong track and tear up a few behavioural tests. Usually that's because you misunderstood the requirements, not how to code it, and that's where the value lies. If you cant write a behavioural test, then you haven't understood the problem fully. If you don't understand the users problem, why are you coding?

That's why initially, its tempting to TDD blindly, you can ignore certain aspects of the users problem and just simply code until you think you got it right. Of course there are a few other aspects to BDD that I'm sure you're either aware of, or hopefully discover after reading this, but its important to remember:

BDD isn't something new and funky fresh. Its not the latest soda pop fad. At its heart its simply TDD Done Well.


Filed under:  | 
 Monday, September 29, 2008

In my previous post I espoused my latest love affair for Stackoverflow. I still think its an awesome site, however I recently got stung by the ever present reality that there are some people who think its for programming questions only, and others who think its for all questions, as long as they relate to programming.

I asked this question.

Sure its subjective, sure it can involve answers that apply to life in general. I even knew that it might yield answers that were opinions rather than fact. However, its firmly under the banner of questions that can be answered. Your answer might work for you and not for me, but that doesn't mean we haven't answered the question, it means the question has more than one answer. Much like the difference between a maze and a labyrinth.

I'm of the opinion that this site was created to provide value to its members. Clearly the response to the question indicates that many members found it to be a useful one. Unfortunately I'm at the mercy of editors who may or may not have a clear grasp of Venn Diagrams. I was told that my question is not about programming because its answers can be applied to any profession.

"This is nothing to do with programming - it applies to all working people"

 

Programming is a subset of the set: Professions. 

Given the above diagram we can posit that a question that applies to all professions also applies to the profession of programming. Especially since I'm a programmer asking other programmers!

In another comment, emphasis mine:

"It's like asking how to make a peanut butter and jelly sandwich suitable for eating while coding - just because it's valuable to many programmers does not make it a programming question."

I'm concerned that semantics is more important to the commenter than good content when I see this. If peanut butter and jam sandwich recipes were truly useful to many programmers then why would we want to stop people from using the site to discuss it? If its useful, its a tool like any other. Discussing techniques to combat lack of motivation are as important as techniques to combat code coupling. 

Furthermore, in light of the fact that the site creators clearly condone this question I'd say that the FAQ was deliberately using soft terminology when guiding the end user what not to ask:

"Avoid asking questions that are subjective, argumentative, or require extended discussion."

Blind adherence to the literal meaning to such a mantra is what gives us such wonderful things as fundamentalism. The spirit of what is going on behind such a sentence is to prevent questions like "Which is better, C# or VB?", not potentially useful discussion.

The key here is that if you choose to take the FAQ literally then you should also take this literally:

As long as your question is:

  • detailed and specific
  • written clearly and simply
  • of interest to at least one other programmer somewhere

... it is welcome here.

I realize that there is a worry about Signal to Noise ratio, but the site is tagged and searchable for heavens sake. Presumably in future releases we'll have the ability to filter out tags in your search results at whim and will anyway.

The fact remains, subjective questions are some of the most popular on the site. Some see this as a scourge that needs to excommunicated. Personally I think it demonstrates that programmers on the whole :

a) Like to have a bit of fun from time to time,

b) Recognize that there is more to programming than code.

All of this is moot however, given that those people who think that all time management solutions in the profession of personal training necessarily applies to that of a surgeon and therefore programmers are clearly wrong.

Let me demonstrate with a small sample of the sorts of differences we are likely to find across two different professions:

Q: When is it a good time to stop coding?

A: Whenever you feel tired and unmotivated. Get up and walk around, maybe get some exercise and get the blood flowing.

Now lets apply this to the profession of say, soldiering:

Q: When is it a good time to stop shooting at the enemy?

I think its clear that ceasing to fire upon the enemy and then getting up and having a walk around when you are simply tired and unmotivated, could result in the untimely cessation of your career as a soldier.

I'm keen to hear others thoughts on the matter.


Filed under:  | 
 Tuesday, September 23, 2008

So I found a new addiction last night. I decided to check out http://stackoverflow.com last night for the first time. Yes I know I'm late to the party, but since I love to share....I will :D

What hooked me was three things that were really easy to achieve:

1) Registering and logging in.

2) Navigating and finding interesting and relevant information.

3) Helping others else out with answers to their questions.

I haven't actually asked a question yet, although from what I've seen that's just as good as the rest of it.

Another thing that leaves me in awe is that nobody has done this as good as stack overflow before. Q&A websites aren't a new thing. But Jeff Atwood, Joel Spolsky et al. simply took an old format and brought some new innovations to it, as well as spending some real effort in the finer details.

For those of you as yet unaware of stack overflow, the primary driving force is a score based incentive system that encourages users to contribute and to contribute appropriately. The more appropriately you contribute, the higher the level of privilege you gain. You can essentially earn your moderator status without permission from err...other moderators.

Even if you don't necessarily provide the best answer, the scoring system allows other people in the community to call out the bad answers and provide better answers. Once you've earned yourself a good enough score (reputation) you can also mark down answers you feel to be erroneous. Anyway I've harped on about how it works for long enough....visit the site and check it out for yourself.

This new(ish) website is a great example of somebody or a group of people just getting in there and doing something and doing it better. Rather than trying to dream up the next killer app, they took a generic idea and absolutely nailed it like its never been nailed before.

I know I am going to learn a  lot from this place, and I'm very excited to have new means to directly help others in my community from the comfort of my lounge room.


Filed under:  | 
 Thursday, September 18, 2008

I often start personal coding projects on a weekend because I am passionate about programming. I wouldn't be here if I wasn't. The problem is that those projects don't get finished very often. The sorts of projects I do find myself finishing are the ones when I've been truly interested in the problem domain.

This isn't a ground breaking revelation. I just have to remind myself of this every now and again. My problem is not that I need to develop with passion, rather I should attempt to develop for things I am passionate about.

Being passionate about programming gives me a special benefit: I can come up with useful ideas for other programmers and implement them.

Unfortunately coming up with cool ideas for programming usually ends in finding somebody else is already halfway through implementing it.

Time to revisit my alt.pursuits for inspiration.


Filed under:
 Wednesday, September 10, 2008

 

Its been a while but F# and Project Euler have been on my mind of late. Problem four plays with palindromes.

Find the largest palindrome made from the product of two 3-digit numbers.

What I like about this question is that we can still break out the math and improve on the obvious brute force method. For instance the palindrome we are after can be written as ABCCBA which can be simplified thusly:

100000a + 10000b + 1000c + 100c + 10b + a

= 100001a + 10010b + 1100c

By finding the lowest common factor for a, b & c we can prove our palindrome must be divisible by that factor. In this case, it happens to be:

11(9091a + 910b + 100c)

So our palindrome must be divisible by 11.

Armed with this knowledge we can hunt for numbers divisible by 11 that are between 100000 and 998001 that are palindromic and choose the biggest one. Using F# we can take advantage of list comprehension, lambdas and some great built in functionality.

In this case I want a list of products of 11 that will match the pattern ABCCBA. This means I can ignore integers below 100 as factors since 99*99=9801 and doesn't fit the ABCCBA pattern. In F# this can be achieved like this:

let products = [ for x in 110 .. 11 .. 999 do for y in 100 .. 999 -> x * y ]

In this example we are taking the multiples of 11 between 110 and 999 and assigning it to x, and then assigning y a number between 100 and 999 and then yielding the product of x and y.

The next trick we need is to be able to check if a number is palindromic. The .NET framework has no real built in for this, but we can use the F# Array class to reverse arrays. Lucky us, because the String class implements seq<char>. That is to say in F# we can treat strings as sequences of chars and indirectly as Arrays:

let reverse_string (s:string) = 
    new string(s |> Seq.to_array |> Array.rev)

Using a function like this we could compare the original string with the reverse to tell if it is indeed a palindrome. Finally we can use List.max to choose the max value of a list.

Putting these techniques together makes for an elegant solution:

#light
let solve() =  
   [ for x in 110 .. 11 .. 999 do for y in 100 .. 999 -> x * y ] 
   |> List.filter (fun x -> x.ToString() = new string( x.ToString() |> Seq.to_array |> Array.rev )) 
   |> List.max

In the above code I hope you can see how I'm using the string reversal code in a lambda expression to filter the non-palindromic numbers out of the list. Once I've done that List.max outputs the final answer. On my dev box, this runs in under 2 tenths of a second. Not bad... Hopefully I'll get some time to compare a similar C# solution. I'll bet C# is faster, but I won't be solving this problem in 4 readable lines...

Oh...and if you can see a more optimal approach please share!


Filed under:
 Tuesday, September 09, 2008

I know its minor and easily fixed but I have to say that I really hate this about 3rd party installations to Visual Studio. I get quite used to certain keyboard shortcuts for every day tasks and the last thing I need is my F12 key hijacked.

Some products are great about this aspect of tool development, some aren't. What I didn't expect was the recent F# CTP to do it to me. In fairness, it is still essentially in beta.

One of the great Visual Studio features of late has surely been smart tags in code, which can be expanded using Ctrl+. or the abominable Shift+Alt+F10:

Smart tag expansion from a C# code file

So, if you too are fond of using the Ctrl+. combo in Visual Studio to expand smart tags to do things quickly like include references, insert using statements and correct syntax errors and you want the latest F# goodies then for the time being you'll need to re-map the key combo. Or you could use the alternative wrist bender Shift+Alt+F10, and for me that was not an option.

To do this, open the Options dialogue from the Tools menu in Visual Studio. Browse to the Keyboard options under the Environment heading and re-map the View.ShowSmartTag command.

Remapping the View.ShowSmartTag back to its original state

I've written to F# feedback to let them know about this minor issue.

***UPDATE***

Luke Hoban from  F# Bug reports confirms this workaround and assures me that this will be included in a soon to be released list of known issues. Thanks Luke!


Filed under:  | 

Just a quick post to highlight the recent release of the F# compiler for Visual Studio. This release shows some real improvement upon the IDE integration featuring true F# project files and an improved language service which benefits both intellisense and background compilation.

I didn't realise how much I liked Visual Studio projects until I was deprived of their functionality. Just simply having a project file that operates like C# or VB projects is a real boon to F# newbies and experts alike.

My previous experiences with intellisense in F# were such that I would often ignore it as it was easily confused. This appears to be less of a problem now and is much more of a help than a hindrance.

So if you haven't already, download and install the F# September CTP from the MS download centre and have a look.


Filed under:  |  |  | 
 Wednesday, August 27, 2008

While reading Chuck's excellent post on the value of both knowing your problem domain before tackling your problem and checking in often, I found myself nodding profusely. I love it... he states:

Write tests first! Do it! DO IT NOW.

I'd like to add: NOW CHECK IN!!

I wish I could...often my problem is *when* to check in. I know I have to do it often, but when? After I finish a task? What if that is a few days away? What is a reasonable amount of time?

When I say task I am referring to a TFS work item. Since we are a scrum shop now it is actually a sprint backlog item. I have TDD at my side, and we have CI builds at work. Why not check in after every passing test cycle?

To be honest, checking in after every passing test feels like I'm wasting more time doing the check in dance, than I am saving time. Having said that, it appears that this is a widely accepted approach. 

Martin Fowler suggests otherwise. It appears he is task oriented when it comes to checking in:

Now I take my working copy and do whatever I need to do to complete my task. This will consist of both altering the production code, and also adding or changing automated tests.

...

With a good build, I can then think about committing my changes into the repository.

I think it feels more natural that way. Its like a 'reward' for finishing a task. The feedback loop advantage of TDD isn't hindered by the longer feedback time of a CI build so much.

However, I'm often left with sprint backlog items whose scope might mean that I'm programming for days on end. This is the root of check in evil for me. If a work item is so broad that it will take days to complete, then the impetus to check in is diminished such that I can get so wrapped up in the detail of the problem that I will forget to check in.

And that's my fault.

I'd love to blame it on the process but I can't. Sure the analysis of the product backlog item could have been more thorough, but we don't want to get too far into implementation details at that point or else we waste the whole teams time.

I should have the sense upon undertaking a task that has been written up as "Import old Foo data for Foo version 2", to split it up in to its discreet units of work. There are SQL tables to write create scripts for. There is a transformation layer to design and implement. There is deployment to think about. Acceptance testing. So on and so forth.

It is *my job* to define the goals on the road to task completion.

Carve up vague work items into byte sized pieces

So I come full circle and refer back to Chuck's post and the idea that we should think about what we are going to do before we go and do it. Coding from hip make pain for coder </grunt>

Accept a task and analyse the problem domain.

Divide it up into check in sized work items.

Eat. Repeat.


© Copyright 2009 Jim Burger