Archive for the ‘.net’ tag
Functional C#: Using Join and GroupJoin
An interesting problem which I've come across a few times recently is where we have two collections which we want to use together in some way and get a result which could either be another collection or some other value.
In one which Chris and I were playing around with we had a collection of years and a collection of cars with corresponding years and the requirement was to show all the years on the page with the first car we found for that year or an empty value if there was no car for that year.
We effectively needed to do a left join on the cars collection.
This is an imperative way of solving the problem:
public class Car { public int Year { get; set; } public string Description { get; set; } }
var years = new[] { 2000, 2001, 2002, 2003 }; var cars = new[] { new Car { Year = 2000, Description = "Honda" }, new Car { Year = 2003, Description = "Ford" } }; var newCars = new List<Car>(); foreach (var year in years) { var car = cars.Where(x => x.Year == year).FirstOrDefault() ?? new Car { Year = year, Description = ""}; newCars.Add(car); }
We can actually achieve the same result in a more declarative way by making use of 'GroupJoin':
var newCars = years.GroupJoin(cars, year => year, car => car.Year, (year, theCars) => theCars.FirstOrDefault() ?? new Car { Year = year, Description = "" });
'GroupJoin' is useful if we want to keep all of the items in the first collection and get a collection of the items in the second collection which match for the specified keys.
In this case it allows us to identify where there are no matching cars for a specific year and then just set a blank description for those years.
One nice side effect is that if we later want to include multiple cars for a year then we shouldn't have to change the code too much to achieve that.
Another example which I came across is where we have one collection which contains filter criteria which it needs to apply against the other collection.
We have a collection of years and need to indicate whether there is a matching car for each of those years.
[Test] public void JoinExample() { var years = new[] { 2000, 2003 }; var cars = new[] { new Car { Year = 2000, Description = "Honda" }, new Car { Year = 2003, Description = "Ford" }, new Car { Year = 2003, Description = "Mercedes"}}; Assert.That(AreThereMatchingCars(years, cars), Is.True); }
public bool AreThereMatchingCars(IEnumerable<int> years, IEnumerable<Car> cars) { foreach (var year in years) { if(cars.Where(c => c.Year == year).Count() == 0) { return false; } } return true; }
We can rewrite this function like so:
public bool AreThereMatchingCars(IEnumerable<int> years, IEnumerable<Car> cars) { var distinctCars = cars.GroupBy(x => x.Year).Select(x => x.First()); return years.Join(distinctCars, y => y, c => c.Year, (y, c) => c).Count() == years.Count(); }
This actually become more complicated than we expected because we were working out if there were matching cars for each of the specified years by checking the number of filter items and then comparing it to the number of items when we joined that collection with our collection of cars.
If we have more than one car for the same year that logic falls down so we needed to get just one car per year which is what the first line of the function does.
I can't decide whether or not the code is easier to read and understand by making use of these functions but it's an approach that I picked up when playing around with F# so it's interesting that it can still be applied in C# code as well.
C#: Overcomplicating with LINQ
I recently came across an interesting bit of code which was going through a collection of strings and then only taking the first 'x' number of characters and discarding the rest.
The code looked roughly like this:
var words = new[] {"hello", "to", "the", "world"}; var newWords = new List<string>(); foreach (string word in words) { if (word.Length > 3) { newWords.Add(word.Substring(0, 3)); continue; } newWords.Add(word); }
For this initial collection of words we would expect 'newWords' to contain ["hel", "to", "the", "wor"]
In a way it's quite annoying that the API for 'Substring' throws an exception if you try and get just the first 3 characters of a string which contains less than 3 characters. If it didn't do that then we would have an easy 'Select' call on the collection.
Instead we have an annoying if statement which stops us from treating the collection as a whole – we do two different things depending on whether or not the string contains more than 3 characters.
In the spirit of the transformational mindset I tried to write some code using functional collection parameters which didn't make use of an if statement.
Following this idea we pretty much have to split the collection into two resulting in this initial attempt:
var newWords = words .Where(w => w.Length > 3) .Select(w => w.Substring(0, 3)) .Union(words.Where(w => w.Length <= 3).Select(w => w));
This resulted in a collection containing ["hel", "wor", "to", "the"] which is now in a different order to the original!
To keep the original order I figured that we needed to keep track of the original index position of the words, resulting in this massively overcomplicated version:
var wordsWithIndex = words.Select((w, index) => new { w, index }); var newWords = wordsWithIndex .Where(a => a.w.Length >= 3) .Select((a, index) => new {w = a.w.Substring(0, 3), a.index}) .Union(wordsWithIndex.Where(a => a.w.Length < 3).Select(a => new { a.w, a.index })) .OrderBy(a => a.index);
We end up with a collection of anonymous types from which we can get the transformed words but it's a far worse solution than any of the others because it takes way longer to understand what's going on.
I couldn't see a good way to make use of functional collection parameters to solve this problem but luckily at this stage Chris Owen came over and pointed out that we could just do this:
var newWords = words.Select(w => w.Length > 3 ? w.Substring(0, 3) : w);
I'd been trying to avoid doing what is effectively an if statement inside a 'Select' but I think in this case it makes a lot of sense and results in a simple and easy to read solution.
Functional C#: Writing a 'partition' function
One of the more interesting higher order functions that I've come across while playing with F# is the partition function which is similar to the filter function except it returns the values which meet the predicate passed in as well as the ones which don't.
I came across an interesting problem recently where we needed to do exactly this and had ended up taking a more imperative for each style approach to solve the problem because this function doesn't exist in C# as far as I know.
In F# the function makes use of a tuple to do this so if we want to create the function in C# then we need to define a tuple object first.
public class Tuple<TFirst, TSecond> { private readonly TFirst first; private readonly TSecond second; public Tuple(TFirst first, TSecond second) { this.first = first; this.second = second; } public TFirst First { get { return first; } } public TSecond Second { get { return second; } } }
public static class IEnumerableExtensions { public static Tuple<IEnumerable<T>, IEnumerable<T>> Partition<T>(this IEnumerable<T> enumerableOf, Func<T, bool> predicate) { var positives = enumerableOf.Where(predicate); var negatives = enumerableOf.Where(e => !predicate(e)); return new Tuple<IEnumerable<T>, IEnumerable<T>>(positives, negatives); } }
I'm not sure of the best way to write this function – at the moment we end up creating two iterators to cover the two different filters that we're running over the collection which seems a bit strange.
In F# 'partition' is on List so the whole collection would be evaluated whereas in this case we're still only evaluating each item as it's needed so maybe there isn't a way to do it without using two iterators.
If we wanted to use this function to get the evens and odds from a collection we could write the following code:
var evensAndOdds = Enumerable.Range(1, 10).Partition(x => x % 2 == 0); var evens = evensAndOdds.First; var odds = evensAndOdds.Second;
The other thing that's nice about F# is that we can assign the result of the expression to two separate values in one go and I don't know of a way to do that in C#.
let evens, odds = [1..10] |> List.partition (fun x -> x % 2 = 0)
We don't need to have the intermediate variable 'evensAndOdds' which doesn't really add much to the code.
I'd be interested in knowing if there's a better way to do this than what I'm trying out.
Functional collectional parameters: Some thoughts
I've been reading through a bit of Steve Freeman and Nat Pryce's 'Growing Object Oriented Software guided by tests' book and I found the following observation in chapter 7 quite interesting:
When starting a new area of code, we might temporarily suspend our design judgment and just write code without attempting to impose much structure.
It's interesting that they don't try and write perfect code the first time around which is actually something I thought experienced developers did until I came across Uncle Bob's Clean Code book where he suggested something similar.
One thing I've noticed when working with collections is that if we want to do something more complicated than just doing a simple map or filter then I find myself initially trying to work through the problem in an imperative hacky way.
When pairing it sometimes also seems easier to talk through the code in an imperative way and then after we've got that figured out then we can work out a way to solve the problem in a more declarative way by making use of functional collection parameters.
An example of this which we came across recently was while looking to parse a file which had data like this:
some,random,data,that,i,made,up
The file was being processed later on and the values inserted into the database in field order. The problem was that we had removed two database fields so we needed to get rid of the 2nd and 3rd values from each line.
var stringBuilder = new StringBuilder(); using (var sr = new StreamReader("c:\\test.txt")) { string line; while ((line = sr.ReadLine()) != null) { var values = line.Split(','); var localBuilder = new StringBuilder(); var count = 0; foreach (var value in values) { if (!(count == 1 || count == 2)) { localBuilder.Append(value); localBuilder.Append(","); } count++; } stringBuilder.AppendLine(localBuilder.ToString().Remove(localBuilder.ToString().Length - 1)); } } using(var writer = new StreamWriter("c:\\newfile.txt")) { writer.Write(stringBuilder.ToString()); writer.Flush(); }
If we wanted to refactor that to use a more declarative style then the first thing we'd look to change is the for loop populating the localBuilder.
We have a temporary 'count' variable which is keeping track of which column we're up to and suggests that we should be able to use one of the higher order functions over collection which allows us to refer to the index of the item.
In this case we can use the 'Where' function to achieve this:
... while ((line = sr.ReadLine()) != null) { var localBuilder = line.Split(','). Where((_, index) => !(index == 1 || index == 2)). Aggregate(new StringBuilder(), (builder, v) => builder.Append(v).Append(",")); stringBuilder.AppendLine(localBuilder.ToString().Remove(localBuilder.ToString().Length - 1)); }
I've been playing around with 'Aggregate' a little bit and it seems like it's quite easy to overcomplicate code using that. It also seems that when using 'Aggregate' it makes sense if the method that we call on our seed returns itself rather than void.
I didn't realise that 'Append' did that so my original code was like this:
var localBuilder = line.Split(','). Where((_, index) => !(index == 1 || index == 2)). Aggregate(new StringBuilder(), (builder, v) => { builder.Append(v); builder.Append(","); return builder; });
I think if we end up having to call functions which return void or some other type then it would probably make sense to add on an extension method which allows us to use the object in a fluent interface style.
Of course this isn't the best solution since we would ideally avoid the need to remove the last character to get rid of the trailling comma which could be done by creating an array of values and then using 'String.Join' on that.
Given that I still think the solution written using functional collection parameters is easier to follow since we've managed to get rid of two variable assignments which weren't interesting as part of what we wanted to do but were details about that specific implementation.
C#: Removing duplication in mapping code with partial classes
One of the problems that we've come across while writing the mapping code for our anti corruption layer is that there is quite a lot of duplication of mapping similar types due to the fact that each service has different auto generated classes representing the same data structure.
We are making SOAP web service calls and generating classes to represent the requests and responses to those end points using SvcUtil. We then translate from those auto generated classes to our domain model using various mapper classes.
One example of duplication which really stood out is the creation of a 'ShortAddress' which is a data structure consisting of a postcode, suburb and state.
In order to map address we have a lot of code similar to this:
private ShortAddress MapAddress(XsdGeneratedAddress xsdGeneratedAddress) { return new ShortAddress(xsdGeneratedAddress.Postcode, xsdGeneratedAddress.Suburb, xsdGeneratedAddress.State); }
private ShortAddress MapAddress(AnotherXsdGeneratedAddress xsdGeneratedAddress) { return new ShortAddress(xsdGeneratedAddress.Postcode, xsdGeneratedAddress.Suburb, xsdGeneratedAddress.State); }
Where the XsdGeneratedAddress might be something like this:
public class XsdGeneratedAddress { string Postcode { get; } string Suburb { get; } string State { get; } // random other code }
It's really quite boring code to write and it's pretty much exactly the same apart from the class name.
I realise here that if we were using a dynamic language we wouldn't have a problem since we could just write the code as if the object being passed into the method had those properties on it.
Sadly we are in C# which doesn't yet have that capability!
Luckily for us the SvcUtil generated classes are partial classes so (as Dave pointed out) we can create another partial class which inherits from an interface that we define. We can then refer to types which implement this interface in our mapping code, helping to reduce the duplication.
In this case we create a 'ShortAddressDTO' with properties that match those on the auto generated class:
public interface ShortAddressDTO { string Postcode { get; } string Suburb { get; } string State { get; } }
We then need to make the generated classes inherit from this:
public partial class XsdGeneratedAddress : ShortAddressDTO {}
Which means in our mapping code we can now do the following:
private ShortAddress MapAddress(ShortAddressDTO shortAddressDTO) { return xsdGeneratedAddress.ConvertToShortAddress(); }
Which uses this extension method:
public static class ServiceDTOExtensions { public static ShortAddress ConvertToShortAddress(ShortAddressDTO shortAddressDTO) { return new ShortAddress(shortAddressDTO.Postcode, shortAddressDTO.Suburb, shortAddressDTO.State); } }
Which seems much cleaner than what we had to do before.
Brownfield Application Development in .NET: Book Review
The Book
Brownfield Application Development in .NET by Kyle Baley and Donald Belcham
The Review
I asked to be sent this book to review by Manning as I was quite intrigued to see how well it would complement Michael Feather's Working Effectively with Legacy Code, the other book I'm aware of which covers approaches to dealing with non green field applications.
What did I learn?
- The authors provide a brief description of the two different approaches to unit testing – state based and behaviour based – I'm currently in favour of the latter approach and Martin Fowler has a well known article which covers pretty much anything you'd want to know about this topic area.
- I really like the section of the book which talks about 'Zero Defect Count', whereby the highest priority should be to fix any defects that are found in work done previously rather than racing ahead onto the next new piece of functionality:
Developers are geared towards driving to work on, and complete, new features and tasks. The result is that defect resolution subconsciously takes a back seat in a developer’s mind.
I think this is quite difficult to achieve when the team is getting pressure to complete new features but then again it will take longer to fix defects if we leave them until later since we need to regain the context around them which is more fresh in our mind the earlier we fix them.
- Another cool idea is that of time boxing efforts at fixing technical debt in the code base – that way we spend a certain amount of time fixing one area and when the time's up we stop. I think this will work well as an approach as often when trying to fix code we can either get into the mindset of not fixing anything at all because it will take too long to do so or ending up shaving the yak in an attempt to fix a particularly problematic area of code.
- I like the definition of abstraction that the authors give:
From the perspective of object- oriented programming, it is the method in which we simplify a complex “thing”, like an object, a set of objects, or a set of services.
I often end up over complicating code in an attempt to create 'abstractions' but by this definition I'm not really abstracting since I'm not simplifying but complicating! This seems like a useful definition to keep in mind when looking to make changes to code.
- Maintainability of code is something which is seriously undervalued – I think it's very important to write your code in such a way that the next person who works with it can actually understand what's going on. The authors have a fantastic quote from Perl Best Practices:
Always code as if the guy who ends up maintaining your code is a violent psychopath who knows where you live.
Writing code that is easy for the next person to understand is much harder than I would expect it to be although on teams which pair programmed frequently I've found the code easier to understand. I recently read a blog post by Jaibeer Malik where he claims that it is harder to read code than to write code which I think is certainly true in some cases.
- There is a discussion of some of the design patterns and whether or not we should explicitly call out their use in our code, the suggestion being that we should only do so if it makes our intent clearer.
- While describing out how to refactor some code to loosen its dependencies it's pointed out that when the responsibilities of a class are a bit fuzzy the name of the class will probably be quite fuzzy too – it seems like this would server as quite a useful indicator for refactoring code to the single responsibility principle. The authors also suggest trying not to append the suffix 'Service' to classes since it tends to be a very overloaded term and a lot of the time doesn't add much value to our code.
- It is constantly pointed out how important it is to do refactoring in small steps so that we don't break the rest of our code and to allow us to get rapid feedback on whether the refactoring is actually working or not. This is something that we've practiced in coding dojos and Kent mentions it as being one of his tools when dealing with code – I've certainly found that the overall time is much less when doing small step refactorings than trying to do everything in one go.
I'm quite interested in trying out an idea called 'Bowling Scorecards' which my former colleague Bernardo Heynemann wrote about – the idea to have a card which has a certain number of squares, each square reprsenting a task that needs to be done. These are then crossed off as members of the team do them.
- An interesting point which is made when talking about how to refactor data access code is to try and make sure that we are getting all the data from a single entry point – this is something which I noticed on a recent project where we were cluttering the controller with two calls to different repositories to retrieve some data when it probably could have been encapsulated into a single call.
- Although they are talking specifically about poor encapsulation in data access layers, I think the following section about this applies to anywhere in our code base where we expose the inner workings of classes by failing to encapsulate properly:
Poor encapsulation will lead to the code changes requiring what is known as the Shotgun Effect. Instead of being able to make one change, the code will require you to make changes in a number of scattered places, similar to how the pellets of a shotgun hit a target. The cost of performing this type of change quickly becomes prohibitive and you will see developers pushing to not have to make changes where this will occur.
- The creation of an anti corruption layer to shield us from 3rd party dependency changes is suggested and I think this is absolutely vital otherwise whenever there is a change in the 3rd party code our code breaks all over the place. The authors also adeptly point out:
The reality is that when you rely on another company's web service, you are ultimately at their mercy. It's the nature of third-party dependencies. You don't have control over them.
Even if we do recognise that we are completely reliant on a 3rd party service for our model I think there is still a need for an anti corruption layer even if it is very thin to protect us from changes.
The authors also describe run time and compile time 3rd party dependencies – I think it's preferable if we can have compile time dependencies since this gives us much quicker feedback and this is an approach we used on a recent project I worked on by making use of generated classes to interact with a SOAP service rather than using WCF message attributes which only provided us feedback at runtime.
In Summary
This book starts off with the very basics of any software development project covering things such as version control, continuous integration servers, automated testing and so on but it gets into some quite interesting areas later on which I think are applicable to any project and not necessarily just 'brownfield' ones.
There is a lot of useful advice about making use of abstractions to protect the code against change both from internal and external dependencies and I particularly like the fact that the are code examples showing the progression of the code through each of the refactoring ideas suggested by the authors.
Definitely worth reading although if you've been working on any type of agile projects then you're probably better off skim reading the first half of the book but paying more attention to the second half.
Functional Collection Parameters: Handling the null collection
One of the interesting cases where I've noticed we tend to avoid functional collection parameters in our code base is when there's the possibility of the collection being null.
The code is on the boundary of our application's interaction with another service so it is actually a valid scenario that we could receive a null collection.
When using extension methods, although we wouldn't get a null pointer exception by calling one on a null collection, we would get a 'source is null' exception when the expression is evaluated so we need to protect ourself against this.
As a result of defending against this scenario we have quite a lot of code that looks like this:
public IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages) { var result = new List<Foo>(); if(fooMessagaes != null) { foreach(var fooMessage in fooMessages) { result.Add(new Foo(fooMessage)); } } return result; }
The method that we want to apply here is 'Select' and even though we can't just apply that directly to the collection we can still make use of it.
private IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages) { if(fooMessages == null) return new List<Foo>(); return fooMessages.Select(eachFooMessage => new Foo(eachFooMessage)); }
There's still duplication doing it this way though so I pulled it up into a 'SafeSelect' extension method:
public static class ICollectionExtensions { public static IEnumerable<TResult> SafeSelect<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) { return source == null ? new List<TResult>() : source.Select(selector) ; } }
We can then make use of this extension method like so:
private IEnumerable<Foo> MapFooMessages(IEnumerable<FooMessage> fooMessages) { return fooMessages.SafeSelect(eachFooMessage => new Foo(fooMessage)); }
The extension method is a bit different to the original way that we did this as I'm not explicitly converting the result into a list at the end which means that it will only be evaluated when the data is actually needed.
In this particular case I don't think that decision will have a big impact but it's something interesting to keep in mind.
C#/F#: Using .NET framework classes
I was recently discussing F# with a couple of colleagues and one thing that came up is the slightly different ways that we might choose to interact with certain .NET framework classes compared to how we use those same classes in C# code.
One of those where I see potential for different use is the Dictionary class.
In C# code when we're querying a dictionary to check that a value exists before we try to extract it we might typically do this:
public string GetValueBy(string key) { var dictionary = new Dictionary<string, string>() { {"key", "value" } }; if(dictionary.ContainsKey(key)) { return dictionary[key]; } return ""; // maybe we'd do something else here but for the sake of this we return the empty string }
There is an alternative way to do this but it makes use of the 'out' keyword so it's generally frowned upon.
public string GetValueBy(string key) { var dictionary = new Dictionary<string, string>() {{"key", "value"}}; string value = ""; dictionary.TryGetValue(key, out value); return value; }
In F# when we make use of a method which effectively defines a second return parameter by using the 'out' keyword the return value of that method becomes a tuple containing that value.
For example when querying Dictionary:
open System.Collections.Generic open System open System.Globalization let testDictionary = let builder = new Dictionary<string, string>() builder.Add("key1", "value") builder let getByKey key = let result, value = testDictionary.TryGetValue(key) if(result) then value result else ""
The return type of TryGetValue is 'bool * string' in this case and by assigning that result to two different values we can get the appropriate values. This is certainly a time when tuples are really useful for simplifying our code.
We could have made use of an 'out' parameter as we did in C# but I think it's much easier to just use the tuple. Dustin Campbell describes the other ways we could extract a value from a dictionary on his blog.
It's not significantly more concise code wise compared to the C# way of doing things although from a brief look at the way that the Dictionary code works in Reflector theoretically we are making less calls to the underlying data structure to get the value from it.
I tried timing 100,000 accesses to a dictionary with each approach to see if the total time would be significantly different but there wasn't any noticeable difference.
There are other 'Try…' methods defined in the base class library – DateTime for example has some more – which I've never used in C# so I'd be intrigued to see whether other languages that run on the CLR will make use of these methods.
Real World Functional Programming: Book Review
The Book
Real World Functional Programming by Tomas Petricek with Jon Skeet (corresponding website)
The Review
I decided to read this book after being somewhat inspired to learn more about functional programming after talking with Phil about his experiences learning Clojure. I'm currently working on a .NET project so it seemed to make sense that F# was the language I picked to learn.
What did I learn?
- I've worked with C# 3.0 since around July 2008 so I had a bit of experience using some of the functional features in C# before picking up this book. I therefore found it very interesting to read about the history of lambda and the different functional languages and how they came into being. Having this as an opening chapter was a nice way to introduce the functional approach to programming.
- Immutable state is one of the key ideas in functional programming – this reminded me of a Joe Armstrong video I watched last year where he spoke of his reduced need to use a debugger when coding Erlang due to the fact that there was only one place where state could have been set rather than several as is the case with a more imperative approach. We have been trying to code with immutable state in mind in our coding dojos and while it takes a bit more thinking up front, the code is much easier to read when written that way.
- Separating the operations from the data is important for allowing us to write code that can be parallelised, focusing on what to do to the data rather than how to do it. Sadek Drobi has a nice illustration of what he calls mosquito programming vs functional programming on page 14 of the slides of his QCon presentation. It describes this idea quite nicely.
- A cool technique that Phil taught me when reading language related books is to have the PDF of the book on one side of the screen and the REPL (in this case F# interactive) on the other side so that you can try out the examples in real time. The book encourages this approach and all the examples follow on from previous ones which I think works quite well for gradually introducing concepts.
- Functions are types in functional programming – I have had a bit of exposure to this idea with Funcs in C# but partial function application is certainly a new concept to me. I can certainly see the value in this although it took me a while to get used to the idea. I am intrigued as to where we should use a functional approach and where an OO approach when working in C#. I think both have a place in well written code.
- F#'s implicit static typing is one of my favourite things about the language – you get safety at compile time but you don't waste a lot of code writing in type information that the compiler should be able to work out for you. It has the strongest type inference of any language that I've worked with and I thought it was quite nice that it was able to work stuff out for me instead of me having to type it all out.
- I really like the idea of option types which I first learnt about from the book. Having the ability to explicitly define when a query hasn't worked is far superior to having to do null checks in our code or the various strategies we use to get around this.
- I thought it was cool that in the early chapters the focus with the F# code is to provide examples that you can just get running straight away instead of having to worry about the need to structure your code in a maintainable way. After I had a reasonable grasp of this then the chapter about using record types to structure code in an OO way come up. I still prefer the C# style of structuring code in objects – it just feels more natural to me at the moment and manages the complexity more easily. It is quite easy to switch between the two styles using features like member augmentation so I think it's probably possible to mix the two styles quite easily.
- We can use modules to make F# functions which don't fit onto any class available from C# code. The code is not as clean as if we were writing just for it to be used by other F# code but it's not too bad:
module Tests = let WithIncome (f:Func<_, _>) client = { client with Income = f.Invoke(client.Income) }
We can then call this in our C# code like so:
Tests.WithIncome(income => income + 5000, client);
Dave Cameron has written more about this.
- Although I studied data structures at university I don't really pay a great deal of attention to them in terms of performance normally so it was interesting to see the massive performance hit that you take when appending a value to the end of an F# list compared to adding it to the beginning. F# uses linked lists so if we want to add something to the end then there is a lot of recursion involved to do that which is quite costly. In terms of big O notation we go from O(N) where N is the number of elements to append to O(N*M) in terms of performance.
- Chapter 13 is about parallel processing of data for which I found I needed to download the Microsoft Parallel Extensions to .NET Framework 3.5, June 2008 Community Technology Preview and then add a reference to 'C:\Program Files\Microsoft Parallel Extensions Jun08 CTP\System.Threading.dll' in order to make use of those features.
- The author provides a nice introduction to continuations and how you can make use of them in F# by using continuation passing style. I'm intrigued as to how we can make use of these in our code – we do a bit already by making use of callbacks which get fired at a later point in our code – but from what I've read it sounds like we should be able to do even more especially when writing web applications.
- Asynchronous workflows are also made very accessible in this book – I had previously struggled a bit with them but the author covers the various API methods available to you and then explains what is going on behind the syntactic sugar that F# provides. I have made some use of these in the little twitter appication that I've been working on now and again.
In Summary
I really enjoyed reading this book – it's my first real foray into the world of functional programming since university and I think I understand the functional approach to programming much better than I did back then from reading this book.
It takes an approach of introducing various functional programming concepts before showing examples of where that concept might come in useful when coding. It's also particularly useful that examples are shown in C# and F# as this made it much easier for me to understand what the F# code was doing by comparing it with the code in a more familiar language.
I'd certainly recommend this to any .NET developers curious about learning how to apply ideas derived from functional programming to their C# code and indeed to any developers looking to start out learning about functional programming.
C#: Using virtual leads to confusion?
A colleague and I were looking through some code that I worked on a couple of months ago where I had created a one level hierarchy using inheritance to represent the response status that we get back from a service call.
The code was along these lines:
public class ResponseStatus { public static readonly ResponseStatus TransactionSuccessful = new TransactionSuccessful(); public static readonly ResponseStatus UnrecoverableError = new UnrecoverableError(); public virtual bool RedirectToErrorPage { get { return true; } } } public class UnrecoverableError : ResponseStatus { } public class TransactionSuccessful : ResponseStatus { public override bool RedirectToErrorPage { get { return false; } } }
Looking at it now it does seem a bit over-engineered, but the main confusion with this code is that when you click through to the definition of 'RedirectToError' it goes to the ResponseStatus version of that property and it's not obvious that it is being overridden in a sub class, this being possible due to my use of the virtual key word.
You therefore need to look in two places to work out what's going on which isn't so good.
A solution which we came up with which is a bit cleaner is like so:
public abstract class ResponseStatus { public static readonly ResponseStatus TransactionSuccessful = new TransactionSuccessful(); public static readonly ResponseStatus UnrecoverableError = new UnrecoverableError(); public abstract bool RedirectToErrorPage { get; } } public class UnrecoverableError : ResponseStatus { public override bool RedirectToErrorPage { get { return true; } } } public class TransactionSuccessful : ResponseStatus { public override bool RedirectToErrorPage { get { return false; } } }
When you have more response statuses then I suppose there does become a bit more duplication but it's traded off against the improved ease of use/reading that we get.
It's generally considered good practice to favour composition over inheritance and from what I can tell the virtual keyword is only ever going to be useful if you're creating an inheritance hierarchy.
An interesting lesson learned.