Welcome to MSDN Blogs Sign in | Join | Help

Don Syme has been telling me again and again to make my experiences with F# more widely available by putting it on my blog; here is my first attempt at "being a better boy".

I am a big fan of F# and I have recently posted an on hubFS a piece of source code for reading from a SQL stream by using the IEnumerable class. However, the code there had two problems:

  1. You could not reset the connection. That means that even if you output the value of the IEnumerable (for debug purposes, let's say) you started to digest the results of the read and never got them back unless you re-created the IEnumerable.
  2. You could not make sure that the reader is properly closed unless all results are digested (in which case you do close the reader).

We have both looked into the issue and rewrote the actual implementation of IEnumerable.unfold to remedy the issues. Here is the new code that allows to specifcy not only the compute function but also the initialisation and closing function.

module IEnumerable = begin
   open System.Collections
   open System.Collections.Generic

   ///The new IEnumerator with a specific open, compute and close function.
   module IEnumerator = begin
      
let end_of_stream() = 
         raise(
new System.ArgumentException("An attempt was made to move past the end of an IEnumerator")) 
      
let unfolds openf compute closef = 
         
let curr = ref None in
         
let state = ref (openf()) in 
         
let getCurr() = match !curr with None -> end_of_stream() | Some x -> x in 
         
{    new IEnumerator<'b>
               
with get_Current() = getCurr()
               
interface IEnumerator 
               
with get_Current() = box (getCurr())
               and MoveNext() = 
               
let s = !state in
               
match compute s with 
               | None
-> (closef s; curr := None; false
               | Some(r,s)
-> curr := Some r; state := s; true
               
and Reset() = (closef !state; state := openf(); curr := None)
               
interface System.IDisposable
               
with Dispose() = () 
      } 
   end

   ///The new ways to create an IEnumerable from a IEnumerator
   let mk_IEnumerable f = 
   {    
new IEnumerable<'b> with GetEnumerator() = f()
         
interface IEnumerable with GetEnumerator() = (f() :> IEnumerator) }

   ///The new way to create an IEnumerable via the unfolds function.
   let unfolds openf compute closef = mk_IEnumerable (fun () -> IEnumerator.unfolds openf compute closef) end

Now it is clear how to give the SQL reader via IEnumerables back the functionality that was missing,  isn't it?

I am an active reader of the Bizarre Creations forums and I really enjoy the disucssions that go on about PGR 3. Recently, there was an interesting post by jetjaguar with a long explanation of the waiting times for some people in Online Carreer. I could not agree more with his technical arguments. In fact, the whole thread is worth a read!

A little while earlier, I did a back-on-the-envelope calculation on the minimal number of PGR 3 Online Carreer players necessary for short waiting times. The number that came out was 12,000 people at the same time playing OLC!

Today, we released the technical report about the TrueSkill ranking and matchmaking algorithm. It is filled with lots more math than the official TrueSkill details page but it should answer any technical question left.  

In fact, in this report we present an analysis of the logged games of the Halo 2 Beta testing (July 2004 - September 2004). This dataset has now been made publically available for research purposes.

I have recently come across John Langford's Machine Learning Theory Blog. I immediately spent several hours reading through the posts and comments and I can only highly recommend this page to anyone interested in machine learning research subjects.

 

This is my first blog; so far, most information about me and my work could be found at

Ok, let's get started.

 
Page view tracker