Mark Needham

Thoughts on Software Development

Archive for the ‘.NET’ Category

F#: Refactoring to active patterns

with 3 comments

I’ve been playing around with more F# code and after realising that I’d peppered the code with if statements I thought it would be interesting to try and refactor it to make use of active patterns.

The code is part of my F# solution to Roy Osherove’s TDD Kata and is used to parse the input string and find which delimeters are being used.

This is the original code:

    let hasCustomDelimeter (value:string) = value.Length > 2 && "//".Equals(value.Substring(0, 2))
    let hasMultipleDelimeters (value:string) = hasCustomDelimeter value && "[".Equals(value.Substring(2,1))
 
    let delimeter value = if (hasCustomDelimeter value) then value.Substring(2, value.IndexOf("\n") - 2) else ","
    let delimeters (value:string) = Regex.Matches(value, "\[(.)\]") |> 
                                    Seq.cast |> 
                                    Seq.map (fun (x:Match) -> x.Groups) |>
                                    Seq.map (fun x -> x |> Seq.cast<Group> |> Seq.nth 1) |>
                                    Seq.map (fun x -> x.Value) |>
                                    Seq.to_array   
 
    let digits value = 
        let delimeter = delimeter value
        if (hasMultipleDelimeters value) then value.Substring(value.IndexOf("\n")) |> split (delimeters value) |> Array.map parse  
        else if (hasCustomDelimeter value) then value.Substring(value.IndexOf("\n")) |> split [| delimeter |] |> Array.map parse
        else value.Replace("\n", delimeter) |> split [|delimeter |] |> Array.map parse

The active pattern that we want to use is known as a ‘multi case active pattern’ which Chris Smith defines as “partitioning the entirety of the input space into different things”. In this case given an input string we want to determine what type of delimeters are contained within that string.

This is the code after I’d created the active pattern:

    let (|MultipleCustomDelimeters|SingleCustomDelimeter|NoCustomDelimeter|) (value:string) =  
        if (value.Length > 2 && "//".Equals(value.Substring(0, 2))) then
            if ("[".Equals(value.Substring(2,1))) then MultipleCustomDelimeters(delimeters value)
            else SingleCustomDelimeter(delimeter value)
        else NoCustomDelimeter(delimeter value)    
 
    let digits value =  
        match value with 
        | SingleCustomDelimeter(delimeter)     -> value.Substring(value.IndexOf("\n")) |> split [| delimeter |] |> Array.map parse
        | MultipleCustomDelimeters(delimeters) -> value.Substring(value.IndexOf("\n")) |> split delimeters  |> Array.map parse 
        | NoCustomDelimeter(delimeter)         -> value.Replace("\n", delimeter) |> split [|delimeter |] |> Array.map parse

One thing I didn’t realise is that you can set different types for the constructor values of each of the active patterns. In this case I want to match single or multiple delimeters and then return those delimeters. We can define one active pattern which matches a single delimeter and just returns that and then another one which returns an array of delimeters which is quite neat.

The way it works is quite similar to discriminated unions.

I found that that having all the code around parsing the input in the same function made it easier for me to understand that code and I quite like that it’s possible to match the pattern and also get the delimeter/delimeters in one expression.

Although there are more lines of code I think this code is more expressive and it wouldn’t be too hard to add in another active pattern if there’s another delimeter type that needs to be handled.

I can’t decide whether the ‘value.SubString’ and ‘value.Replace’ code should also be contained within the active pattern or not. At the moment I’m thinking perhaps not because it’s not related to the actual delimeters.

Written by Mark Needham

January 7th, 2010 at 11:31 pm

Posted in F#

Tagged with

F#: String.Split with a multi character delimeter

with one comment

In my continued efforts at Roy Osherove’s TDD Kata I’ve been trying to work out how to split a string based on a delimeter which contains more than one character.

My original thinking was that it should be possible to do so like this:

"1***2".Split("***".ToCharArray());;

I didn’t realise that splitting the string like that splits on each of the stars individually which means that we end up getting 2 empty values in the result:

val it : string [] = [|"1"; ""; ""; "2"|]

If we want to split on ‘***’ then we have to pass it in as a value in a string array:

"1***2".Split([| "***" |], StringSplitOptions.None);;

That way we only get the 1 and 2 which is what we want:

val it : string [] = [|"1"; "2"|]

I’d expected there to be an overload which takes in a string and then just splits on that but since there isn’t this isn’t a bad alternative.

Sam Allen has a very interesting article which covers all sorts of way to split different types of strings.

Written by Mark Needham

January 5th, 2010 at 11:10 pm

Posted in F#

Tagged with

F#: Expressing intent and the forward/application operators

with 5 comments

A while ago I wrote about F#’s forward and application operators where I’d looked at how these could be used to simplify code and while trying out Roy Osherove’s TDD Kata I realised that perhaps the choice of which of these to use or whether to use them at all depends on what intent we’re expressing.

The specific bit of code I was writing was for raising an exception if negative values were provided and I originally thought I’d use the forward operator to express this code:

    let digits = [| 1;2;3;-3 |] 
    let buildExceptionMessage negatives = sprintf "No negative numbers allowed. You provided %s" 
                                                  (String.Join(",", negatives |> Array.map (fun x -> x.ToString())))
 
    raise (ArgumentException (digits |> Array.filter (fun x -> x < 0) |> buildExceptionMessage))

I think in this case the forward operator doesn’t actually express the intent of the code better because it puts the focus on the digits rather than on the building of the exception message.

I changed that a bit to emphasise the importance of the ‘buildExceptionMessage’ function:

raise (ArgumentException (buildExceptionMessage (digits |> Array.filter (fun x -> x < 0))))

I thought it might be possible to get rid of the brackets around the filtering of the digits and instead apply that expression to ‘buildExceptionMessage’ using the application operator:

raise (ArgumentException (buildExceptionMessage <| digits |> Array.filter (fun x -> x < 0)))

That actually results in the following error message:

Type mismatch. Expecting a  string -> string but given a  'a array -> 'a array. The type 'string' does not match the type ''a array'

The problem is that it applies digits to ‘buildExceptionMessage’ first and then tries to apply the result of that to Array.filter instead of applying the filter to the digits and then passing the result of that calculation to ‘buildExceptionMessage’.

One way to get around this is to remove the forward operator and move digits to be the second argument passed to Array.filter instead:

raise (ArgumentException (buildExceptionMessage <| Array.filter (fun x -> x < 0) digits))

This is the version that I’ve got at the moment and I think it expresses the intent of the code the best.

I’d be interested in hearing more thoughts on the best way to use or not use these operators in idiomatic F# code.

Written by Mark Needham

January 4th, 2010 at 11:11 am

Posted in F#

Tagged with

F#: Word Count using a Dictionary

with 3 comments

Having spent some time unsuccessfully trying to make my F# attempt at the word count problem work I decided to follow the lead of the other examples I’ve read and make use of a Dictionary to keep count of the words.

I originally thought that I might be having a problem with the downloading of the files and storing of those strings in memory so I tried to change that bit of code to be lazily evaluated:

let downloadFile path = 
    lazy(use streamReader = new StreamReader(File.OpenRead path)
    streamReader.ReadToEnd())

That didn’t seem to make much difference though and it seemed like the StackOverflowException was happening on the ‘List.fold’ line:

let wordCount = files >> 
                List.map downloadFile >>
                List.map words >>
                List.fold (fun acc x -> Seq.append acc x) Seq.empty >> 
                Seq.groupBy (fun x -> x) >> 
                Seq.map (fun (value, sequence) -> (value, Seq.length sequence))

I couldn’t see a way of changing the solution such that the current approach wouldn’t need that line so I rewrote part of it ending up with the following solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#light
#r "FSharp.PowerPack"
open System
open System.IO
open System.Text.RegularExpressions
open System.Collections.Generic
 
let (|File|Directory|) path = if(Directory.Exists path) then Directory(path) else File(path)
let getFileSystemEntries path = Directory.GetFileSystemEntries path |> Array.to_list
 
let files path = 
    let rec inner fileSystemEntries files =
        match fileSystemEntries with
            | [] -> files
            | File path :: rest -> inner rest (path :: files)  
            | Directory path :: rest -> inner (List.append rest (getFileSystemEntries path)) files  
    inner (getFileSystemEntries path) []
 
let download path = using (new StreamReader(File.OpenRead path)) (fun reader -> reader.ReadToEnd())
let writeTo (path:string) f = using (new StreamWriter(path)) (fun writer -> f writer)
 
let words input = Regex.Matches(input, "\w+") |> Seq.cast |> Seq.map (fun (x:Match) -> x.Value.ToLower()) 
let apply (dict:Dictionary<string,int>) key f = if(dict.ContainsKey(key)) then dict.[key] <- f dict.[key] else dict.[key] <- f 0
 
let startTime = DateTime.Now
let dict = new Dictionary<string, int>()
 
files "Z:\\20_newsgroups" |> List.iter (fun file -> download file |> words |> Seq.iter (fun word -> apply dict word ((+) 1) )) 
 
printfn "Writing counts in alphabetical order"
writeTo "C:\\results\\counts-alphabetical-fsharp.txt" (fun out -> 
    dict |> Seq.sortBy (fun x -> x.Key) |> Seq.iter (fun entry -> out.WriteLine(entry.Key + " " + entry.Value.ToString())))
 
printfn "Writing counts in descending order"
writeTo "C:\\results\\counts-descending-fsharp.txt" (fun out -> 
    dict |> Seq.sortBy (fun x -> x.Value * -1) |> Seq.iter (fun entry -> out.WriteLine(entry.Key + " " + entry.Value.ToString())))
 
let endTime = DateTime.Now
printfn "Finished in: %d seconds" (endTime - startTime  ).Seconds

As I wrote about previously I found out that I could use the ‘using’ function instead of the ‘use’ keyword with the ‘StreamWriter’ and ‘StreamReader’ so those bits of code are a bit simplified.

The way of interacting with dictionaries in F# doesn’t seem as nice as in Ruby so I’ve ended up with the somewhat verbose bit of code on line 23. Is there a cleaner way of doing that?

By using a Dictionary I think it’s now more difficult to parallelise the counting up of the words which was something I thought might be possible when I first came across the problem.

This seems like the perfect problem for the MapReduce approach although I’m not quite sure about the implementation details.

My thinking is that we’d have a Dictionary for each node/actor and it would sum up the words in its file before passing the result to another actor which would be responsible for taking all the dictionaries and accumulating the word counts?

This was an interesting problem for showing what happens if you try to store too much data in memory and it’s something that I’ve not come across before because I don’t typically work with data sets that are this big.

Written by Mark Needham

December 20th, 2009 at 10:09 am

Posted in F#

Tagged with

F#: The use keyword and using function

without comments

While I was playing around with the little F# script that I wrote to try and solve the word count problem I noticed that in a couple of places I had used the ‘use‘ keyword when dealing with resources that needed to be released when they’d been used.

Using the ‘use’ keyword means that the ‘Dispose’ method will be called on the resource when it goes out of scope.

The two examples were ‘StreamWriter’ and ‘StreamReader’:

let writeTo (path:string) f = 
    use writer = new StreamWriter(path)
    f writer
let download path = 
    use streamReader = new StreamReader(File.OpenRead path)
    streamReader.ReadToEnd()

I found it quite annoying that those bits of code needed to take up three lines despite the fact I don’t really need to have the class construction assigned.

Luckily there is a ‘using’ function available which allows us to make these bits of code more concise.

‘using’ takes in 2 arguments – the object to be created and a function which takes in that object and does something with it.

If we make use of that function instead of the ‘use’ keyword we end up with the following function definitions:

let writeTo (path:string) f = using (new StreamWriter(path)) (fun writer -> f writer)
let download path = using (new StreamReader(File.OpenRead path)) (fun reader -> reader.ReadToEnd())

When we’re just doing one thing with the resource, as I am here, then I think this reads better. If we’re using it for multiple different operations then perhaps the use keyword is more appropriate.

Written by Mark Needham

December 19th, 2009 at 10:33 am

Posted in F#

Tagged with

F#: Word Count – A somewhat failed attempt

with 2 comments

I came across Zach Cox’s word count problem via Sam Aaron and Ola Bini’s twitter streams and I thought it’d be interesting to try it out in F# to see what the solution would be like.

The solution needs to count word frequencies from a selection of newsgroup articles.

I wanted to see if it was possible to write it in F# without using a map to keep track of how many of each word had been found.

My thinking was that I would need to keep all of the words found and then calculate the totals at the end.

After a bit of fiddling this is the version I ended up with:

word-count.fsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#light
open System
open System.IO
open System.Text.RegularExpressions
 
let (|File|Directory|) path = if(Directory.Exists path) then Directory(path) else File(path)
let getFileSystemEntries path = Directory.GetFileSystemEntries path |> Array.to_list
 
let files path = 
    let rec inner fileSystemEntries files =
        match fileSystemEntries with
            | [] -> files
            | File path :: rest -> inner rest (path :: files)  
            | Directory path :: rest -> inner (List.append rest (getFileSystemEntries path)) files  
    inner (getFileSystemEntries path) []
 
let downloadFile path = 
    use streamReader = new StreamReader(File.OpenRead path)
    streamReader.ReadToEnd()    
 
let words input= Regex.Matches(input, "\w+") |> Seq.cast |> Seq.map (fun (x:Match) -> x.Value.ToLower())
 
let wordCount = files >> 
                List.map downloadFile >>
                List.map words >>
                List.fold (fun acc x -> Seq.append acc x) Seq.empty >> 
                Seq.groupBy (fun x -> x) >> 
                Seq.map (fun (value, sequence) -> (value, Seq.length sequence))
 
let writeTo (path:string) (values:seq<string * int>) = 
    use writer = new StreamWriter(path)
    values |> Seq.iter (fun (value,count) -> writer.WriteLine(value + " " + count.ToString()))  
 
let startTime = DateTime.Now
let count = wordCount "Z:\\20_newsgroups"
 
printfn "Writing counts in alphabetical order"
count |> Seq.sort |> writeTo "C:\\results\\counts-alphabetical-fsharp.txt"
 
printfn "Writing counts in descending order"
count |> Seq.sortBy (fun (_, count) -> count * -1) |> writeTo "C:\\results\\counts-descending-fsharp.txt"
 
let endTime = DateTime.Now
printfn "Finished in: %d seconds" (endTime - startTime).Seconds

The problem is that this version results in a StackOverFlow exception when I try to execute it with all the newsgroup articles although it does work correctly if I select just one of the folders.

From what I can tell the exception happens on line 24 when I get the text out of each of the files and store it in the list.

I tried changing this bit of code so that instead of doing that I combined the ‘words’ and ‘downloadFile’ functions so that the whole string wouldn’t be saved but this doesn’t seem to help that much. The exception just ended up happening a bit further down.

I’m not sure if it’s possible to make this work by making use of lazy collections – I’m not that familiar with those yet so I”m not sure how to do it – or if this approach is just doomed!

Despite the fact it doesn’t quite work there were some interesting things I noticed while playing with this problem:

  • At one stage I was trying to deal with a list of sequences whereby I had a list of sequences of words for each of the newsgroup articles. I found this really difficult to reason about as I was writing a ‘List.map’ and then a ‘Seq.map’ inside that.

    I originally had the ‘List.fold (fun acc x -> Seq.append acc x) Seq.empty’ line happening later on in that composition of functions such that I grouped all the words and then counted how many there were before folding down into a single sequence.

    I realised this didn’t make much sense and it would be much easier to just go to the sequence earlier on and make the code easier to follow.

  • I’ve previously written about wrapping .NET library calls and I was doing this quite a lot when I started writing this code.

    For example I had written a function called ‘isDirectory’ which wrapped ‘Directory.Exists’ which I wrote more out of habit than anything else but it doesn’t really add much value. I think when we’re talking about wrapping static methods this is probably always the case. It’s when we want to call a method on a C# object that the wrapping approach can be helpful.

  • I quite like the Ruby way of writing to a file…
    open("counts-descreasing-ruby", "w") do |out|
      counts.sort { |a, b| b[1] <=> a[1] }.each { |pair| out << "#{pair[0]}\t#{pair[1]}\n" }
    end

    …so I thought I’d see what it would look like to change my ‘writeTo’ function to be more like that:

    let writeTo (path:string) (f: StreamWriter -> Unit) = 
        use writer = new StreamWriter(path)
        f writer
    writeTo "C:\\results\\counts-alphabetical-fsharp.txt" (fun out -> 
        count |> Seq.sort |> Seq.iter (fun (v,c) -> out.WriteLine(v + " " + c.ToString())))

    I’m not sure it reads as well as the original version – the writing to file seems to becomes more prominent in this version than the data being written to it.

If anyone has any ideas about how I can get this not to blow up that would be cool!

These are some of the other solutions that I’ve come across:

Written by Mark Needham

December 18th, 2009 at 2:58 am

Posted in F#

Tagged with

Haskell vs F#: Function composition

with 11 comments

I’m reading through John Hughes’ ‘Why functional programming matters‘ paper and one thing I’ve come across which is a bit counter intuitive to me is the Haskell function composition operator.

I’ve written previously about F#’s function composition operator which is defined as follows:

let inline (>>) f g x = g(f x)

To write a function which doubled all the values in a list and then returned the odd values we’d do this:

let doubleThenOdd = List.map (fun x -> x*2) >> List.filter (fun x -> x % 2 <> 0)

Of course it’s not possible for there to be any values!

doubleThenOdd [1..5];;
val it : int list = []

Based on that understanding I would expect the Haskell function composition operator (‘.’) to work in the same way:

let doubleThenOdd = map (\ x -> x*2) . filter (\ x -> (mod x 2) /= 0)

But it doesn’t!

Prelude> doubleThenOdd [1..5]
[2,6,10]

In Haskell the functions are applied from right to left rather than left to right as I had expected.

The definition of ‘.’ is therefore:

(f . g) x = f (g x)

So to get what I wanted we’d need to switch around ‘map’ and ‘filter’:

let doubleThenOdd = filter (\ x -> (mod x 2) /= 0) . map (\ x -> x*2)
Prelude> doubleThenOdd [1..5]
[]

It’s not too difficult to follow once I worked out that it was different to what I was used to but I was very confused for a while!

Is there a reason why they implement this operator differently?

Written by Mark Needham

December 9th, 2009 at 10:10 pm

Posted in F#

Tagged with ,

Coding: An abstract class/ASP.NET MVC dilemma

with 9 comments

I previously described a refactoring that we have been working on to reduce the number of fields and delay calculations and the actual goal behind this refactoring was to get the code into shape so that we could add in the logic for a new business process that our application needed to handle.

The code in question defines view models being used by different partial views which are rendered depending on the business process that the user is currently executing.

We decided that the best way to add in this new code was drive our code towards a stage where we could have an abstract class and then sub classes for each of the specific business processes around this area.

Before this we had been using the same class everywhere but it was becoming a bit too complicated to understand as we attempted to add in this new functionality – there was already scattered if/else logic for the two business processes that were already being handled in the same place.

The views were defined like this, where the generic type on ‘ViewModel’ is the name of the specific business process model class:

ParentPage.aspx : ViewModel
 
BusinessProcess1Partial.aspx : ViewModel
BusinessProcess2Partial.aspx : ViewModel
BusinessProcess3Partial.aspx : ViewModel

The classes in question are roughly like this:

public abstract class ParentModel
{
	private readonly Dependency dependency;
 
	public ParentModel(Dependency depedency)
	{
		this.dependency = dependency;
	}	
 
	public string GetValueOne()
	{
		return dependency1.GetValueOne();
	}
}
 
public class BusinessProcessModel1 : ParentModel
{
	public BusinessProcessModel1(Dependency dependency) : base(dependency) { }
 
	public int SomeBusinessProcess1SpecificThing()
	{
		// do some calculation
	}
}
 
public class BusinessProcessModel2 : ParentModel
{
	public BusinessProcessModel1(Dependency dependency) : base(dependency) { }
 
	public int SomeBusinessProcess2SpecificThing()
	{
		// do some calculation
	}
}

It worked quite well for the majority of what we wanted to do but we eventually got to the stage where there was a property which we needed on the ‘ParentModel’ for the ‘ParentPage’ which was also needed by BusinessProcessModel1 and BusinessProcessModel2 but not by BusinessProcessModel3.

We actually had the data required for that property at the time of construction of all three of the business processes so we decided to add it to the ‘ParentModel’ and even though it seems quite evil to do this we couldn’t see an immediately obvious alternative.

Our initial thought was that perhaps we could make use of some role based interfaces and then define those interfaces as part of the ‘ViewModel’ generic that each page extends. As far as I understand it’s not possible to do this though because any types we use with ‘ViewModel’ need to be classes.

An approach which we considered but didn’t try out is to have a ‘ParentModel’ representing the top level page and then have each of the business proceess models as propertys on that.

By doing that we could reduce the need to have the class hierarchy although we would increase the complexity of the code for rendering the business process specific partials since we’d need to introduce if statements into the parent view to ensure that the correct property from that was selected.

Neither option seems that great. Has anyone found a better solution?

Written by Mark Needham

September 13th, 2009 at 12:19 am

Posted in .NET,Coding

Tagged with

F#: Playing around with asynchronous workflows

with 2 comments

I spent a bit of time over the weekend playing around with F# asynchronous workflows and seeing how they could be used to launch Firefox windows asynchronously for my FeedBurner graph creator.

Initially I decided to try out the ‘Async.RunWithContinuations’ function which I recently read about on Matthew Podwysocki’s blog.

Matthew describes this as being a function which is useful for executing a single operation asynchronously and this worked out quite well for me as my application only has the ability to get one feed and then create a graph from its data.

I changed the Execute function (which takes in arguments from the command line as I wrote about previously) to launch a firefox window with the graph loaded:

let launchInFirefox url = async { System.Diagnostics.Process.Start(@"C:\Program Files\Mozilla Firefox\firefox.exe", url) |> ignore }
 
let timeNow () = System.DateTime.Now.ToLongTimeString()
 
let Execute args =    
    if (Array.length args <> 3) 
    then printfn "Expected usage: [feedName] [startDate yyyy-mm-dd] [endDate yyyy-mm-dd]" 
    else 
        let feedName, startDate, endDate = args.[0], args.[1], args.[2]
        let graphUri = (ShowFeedBurnerStats feedName startDate endDate).AbsoluteUri
 
        Async.RunWithContinuations ( (fun cont -> printfn "Downloaded feed graph for %s at %s" feedName (timeNow())), 
                                     (fun ex -> printfn "Failed to download feed graph for %s - %s %s " feedName (ex.Message) (ex.StackTrace)), 
                                     (fun cancelled -> printfn "Feed graph downloading for %s was cancelled" feedName),
                                     (launchInFirefox graphUri) )

The function actually takes in three continuations as well as the asynchronous computation to run:

  • A continuation to run if the computation completes successfully
  • An exception continuation to run if the computation throws an exception. I was able to test this out by trying to launch a process which did not exist
  • A cancellation continuation to run if there is a signal for the computation to be cancelled

We then pass in the asynchronous computation as the last argument to the function which in this case is a process which launches FireFox with the url of the graph.

This works quite nicely but you don’t really notice that much different between launching the browser this way and just doing it using the ‘Async.RunSynchronously’ function.

It becomes a bit more interesting if we try to execute more than one asynchronous computations which in this case means creating multiple graphs at the same time.

My first attempt was to launch each of these computations synchronously:

let CreateGraphs (feeds:seq<string>) =
    feeds |> 
    Seq.map (fun f -> ShowFeedBurnerStats f "2009-03-01" "2009-07-25") |>
    Seq.map (fun uri -> launchInFirefox uri.AbsoluteUri ) |> 
    Seq.iter (Async.RunSynchronously)

I called this function like so:

let feeds = seq { yield "markneedham"; yield "scotthanselman"; yield "codethinked"; yield "haacked"; yield "Iserializable" };
CreateGraphs feeds

That works fine although there is a noticeable pause as each of these is loaded into the browser one after the other.

One way to get around this is to make use of the ‘Async.Parallel’ function which converts a sequence of asynchronous computations into a single asynchronous computation which can execute all of the individual asynchronous computations.

I initially got confused here and thought that passing a sequence of asynchronous computations to ‘Async.Parallel’ actually executed them but as I learnt you actually need to pass the result to one of the functions which actually runs the asynchronous computations.

We don’t need to change our function too much to achieve this:

let CreateGraphsParallel (feeds:seq<string>) =
    feeds |> 
    Seq.map (fun f -> ShowFeedBurnerStats f "2009-03-01" "2009-07-25") |>
    Seq.map (fun uri -> launchInFirefox uri.AbsoluteUri ) |> 
    Async.Parallel |>
    Async.RunSynchronously
let feeds = seq { yield "markneedham"; yield "scotthanselman"; yield "codethinked"; yield "haacked"; yield "Iserializable" };
CreateGraphsParallel feeds

The graphs seem to get launched in FireFox much more quickly using this method and there is no real pause, just a flurry of new tabs being launched as each of the graphs is opened.

I thought the ‘Async.Start’ function might allow us to achieve a similar result as the API comments state ‘Start the asynchronous computation in the thread pool. Do not await its result’ but I saw similar behaviour to when I used ‘Async.RunSynchronously’

let CreateGraphsSpawn (feeds:seq<string>) =
    feeds |> 
    Seq.map (fun f -> ShowFeedBurnerStats f "2009-03-01" "2009-07-25") |>
    Seq.map (fun uri -> launchInFirefox uri.AbsoluteUri ) |> 
    Seq.iter(Async.Start)
let feeds = seq { yield "markneedham"; yield "scotthanselman"; yield "codethinked"; yield "haacked"; yield "Iserializable" };
CreateGraphsSpawn feeds

Out of these ‘Async.Parallel’ seems to be the best function to use to get quick feedback from multiple computations.

There are also a few other functions that I haven’t tried out yet and I’m intrigued as to whether we would achieve good results by making use of MailBoxProcessors or not.

Written by Mark Needham

July 26th, 2009 at 11:45 pm

Posted in F#

Tagged with ,

F#: Values, functions and DateTime

without comments

One of the things I’ve noticed recently in my playing around with F# is that when we decide to wrap calls to the .NET DateTime methods there is a need to be quite careful that we are wrapping those calls with an F# function and not an F# value.

If we don’t do this then the DateTime method will only be evaluated once and then return the same value for every call which is probably not the behaviour we’re looking for.

The following shows how we could wrap call to get the current time in string format inside a value:

let timeNow = System.DateTime.Now.ToLongTimeString()

If we then execute ‘timeNow’ to show the current time before and after a sleep this is what we see:

printfn "The time now is %s" timeNow
System.Threading.Thread.Sleep(2000)
printfn "The time now is %s" timeNow
The time now is 2:00:29 PM
The time now is 2:00:29 PM

As we can see the time has remained the same despite the fact that we put a sleep in between thew two calls.

Looking at the C# version of this code via Reflector we can see that ‘timeNow’ is just a string:

public string timeNow;

The way to get the real current time is to define a function to get the time so that it will be reevaluated each time we ask for the time:

let timeNowUpToDate () = System.DateTime.Now.ToLongTimeString()

If we do the same test as we did above:

printfn "The time now is %s" (timeNowUpToDate())
System.Threading.Thread.Sleep(2000)
printfn "The time now is %s" (timeNowUpToDate())

We get the following results:

The time now is 2:05:13 PM
The time now is 2:05:15 PM

Which is what we were looking for in the first place!

Via Reflector again this is what that code would look like in C#:

[Serializable]
internal class timeNowUpToDate@127 : FastFunc<Unit, string>
{
    // Methods
    internal timeNowUpToDate@127()
    {
    }
 
    public override string Invoke(Unit unitVar0)
    {
        return DateTime.Now.ToLongTimeString();
    }
}

As we can see every time the function is invoked a call to the DateTime API will be made which is what we want to happen.

Written by Mark Needham

July 25th, 2009 at 2:10 pm

Posted in F#

Tagged with