Monthly Archives: December 2013

Type Extensions in F#

There are two types of type extensions. The first would be seen more like a partial class in C# and the second are extension methods (in C# language).

Intrinsic Type Extension

So the first type of type extension is an intrinsic extension which appears “in the same namespace or module, in the same source file and in the same assembly as the type being extended” (as take from Type Extensions (F#).

Basically an intrinsic type extension can be compared to a C# partial class. It’s a way of breaking down the implementation of a class into multiple files/locations for maintainability etc.

An example of this syntax is

namespace MyNamespace

module MyType =

    type HelloWorldClass = 
        new() = {}
        member this.Hello() = printfn "hello"
        member this.World() = printfn "world"

    type HelloWorldClass with 
        member this.Exclamation = printfn"!"

The second type declaration using the with keyword to declare the extensions to the type.

Obviously when we create an instance of HelloWorldClass the methods Hello, World and Exclamation are all visible to the calling code as if they’d been writing in the one type declaration.

Options Type Extensions

Similar to the previous type extension in syntax and like C# extension methods will only be visible when loaded. For example if we want to extend a String class to add a method to capitalize the first letter of a string and have the rest lower case we might declare the following

type System.String with
   member this.CapitalizeFirstLetter =
      this.Substring(0, 1).ToUpper() + this.Substring(1).ToLower()

Notice the use of the self identifier used throughout the declaration. In usage this would now appear as an extension to the System.String class and we could use it as follows

let s = "hello"
printfn "%s" <| s.CapitalizeFirstLetter

Using F# from C#

Let’s take a simple example – we have a library in F# which has functions that we want to use in C#. In this case we’ve got a Fibonacci function.

  1. Create a C# console application (for this demo)
  2. Add a new F# Library project (I named mine FLib)
  3. Add the following code to the library
    namespace FLib
    
    module Mathematics =
    
        let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
    

    Note: you must include the module if you want to declare values/functions in a namespace

  4. Now in the C# application add the using clause

    using FLib;
    
  5. And finally we use the function as per the following
    int result = Mathematics.fib(5);
    

    The module appears list a static class with static methods.

Interfaces and Classes in F#

Interfaces

Interfaces are declared in a similar fashion to classes but with only abstract members, for example

type ICalculator =
    abstract member Add : int -> int -> int

Classes

type Calculator() =
    member this.Add a b = a + b

Here we declared a constructor with no arguments, but we could also declare a constructor which takes arguments, such as

type Calculator(a, b) =
        member this.Add = a + b

We can also declare the constructors in the following manner

type Calculator1 =
        new () = {}
        member this.Add = a + b

type Calculator2 =
        new (a, b) = { (* do something with the values *) }
        member this.Add = a + b

Leading on from this way of declaring constructors, we can also declare multiple constructors in the following manner

type SomeClass =
    val data : string
    new () = { data = "undefined"}
    new (d) = { data = d }

Here we’ve declared a default constructor and one which takes a single argument.

or implementing the previously declared ICalculator we have

type Calculator() =
    interface ICalculator with
        member this.Add a b = a + b

To access the Add method we need to cast our value to the specific interfaces, for example

let calc = new Calculator()
(calc :> ICalculator).Add 2 3

The :> is the cast operator.

We can also implement an interface in an anonymous class, for example

let calculator() =
   {
      new ICalculator with
         member this.Add a b = a + b
   }

Inheritance

type Calculator() =
   member this.Add a b = a + b

type NewCalculator() = 
   inherit Calculator()   

Virtual functions

To declare a function as virtual we need to both declare it as abstract and create a default implementation, for example

type MyClass() = 
   abstract member myfunction : unit -> unit
   default u.myfunction() = printfn "hello"

Note: the “u.” part of the above is a self identifier. Unlike C# which has the implicit “this” identifier, we can define whatever name we wish for the self identifier

We can define a self identifier at the class level using

type MyClass() as myself = 
   abstract member myfunction : unit -> unit
   default myself.myfunction() = printfn "hello"

F# basics

Some basics of F#

#light

This directive (hash light) is used to simplify the F# syntax. Meaning the syntax is a little less verbose and removes aspects of the OCaml compatibility.

Immutable by default

By default “variables” are really just “values” as they are immutable by default so

let n = 100

initializes n to the value 100 and you cannot now alter n.

However we can mark a value as mutable and thus is can be altered, for example

let mutable n = 100
n <- n + 1

n is set to be a mutable type and n <- n + 1 is the assignment line of code, assigning n the new value of n + 1.

Assignment operator

As mentioned above, F# values are immutable, by marking them as mutable we can assign values to them. The assignment operator is not = but is <-, for example [code language="fsharp"] let mutable n = 10 // initializes n the value 10 n <- 100 // assignment of the value 100 [/code] ignore

Some functions return values which we might not actually wish to use. For example the following uses List.map to simply output the items in the array urls

let urls = ["http://www.bbc.co.uk";
             "http://www.google.co.uk";
             "http://www.amazon.co.uk"]

let f x = printfn "%s" x
List.map f urls

But the compiler will show a warning This expression should have type ‘unit’, but has type ‘unit list’. Use ‘ignore’ to discard the result of the expression, or ‘let’ to bind the result to a name for the line List.map f urls. To fix this either change this line to

let o = List.map f urls

or pipe the result to ignore as per

List.map f urls |> ignore

We can also use the following syntax

ignore(List.map f urls)

Semi-colon and commas in lists and arrays

To declare a list value in F# we use a semi-colon to denote each value of a list for example

let evens = [2;4;6;8;10;12]

This will create a val evens : int list = [2; 4; 6; 8; 10; 12]

Alternatively using a comma as per

let evens = [2,4,6,8,10,12]

This will create a val evens : (int * int * int * int) list = [(2, 4, 6, 8)]. The difference here is that with the comma we’re creating a tuple containing integers, not a list of integers.

Collection Types

List

A list is declared as

let list = [2;4;6;8;10]

Lists are ordered, immutable data of the same type.

Array

An array is declared as

let array = [|2;4;6;8;10|]

Array’s are fixed-size, zero based values of the same type.

Sequence

A sequence is declared as

let s = seq { 0 .. 10 .. 100 }

A sequence is a series of values of the same type.

Lambda expressions and anonymous functions

Anonymous functions are declared as follows

fun parameter-list -> expression

For example we might use an anonymous function in a List.map as follows

let urls = ["http://www.bbc.co.uk";
             "http://www.google.co.uk";
             "http://www.amazon.co.uk"]

List.map (fun x -> printfn "%s" x) urls

Comments

Single line comments are denoted in the same way as C# i.e.

// This is a comment

Multi-line comments are denoted using (*..*), i.e.

(*
This is a comment block
*)

Loops

The F# equivalent of a foreach

let a = [0 .. 6]
for i in a do
   printfn "%d" i

The for loop

for i = 1 to 10 do
   printfn "%d" i

for j = 10 downto 1 do
   printfn "%d" j

The while loop

let aa = [|0 .. 6|]
let mutable i = 0
  while i < (Array.length aa) do
     printfn "%d" (Array.get aa i)
     i <- i + 1

The unit type

Functions which take no arguments and/or return no values are said to take and return the type unit. This can be seen as being analogous to void in C#.

The double backtick “ in identifiers

As per Identifiers and Keywords. We can use the double backtick “ to enclose identifier that might be a language keyword, for example

let ``private`` = 1

is valid even though private is a keyword. We can also have spaces in identifiers such as

let ``add two numbers`` () =
   // function definition

Modules in F#

Modules allow us to break up source code into multiple files. There are two types of module, a top-level module and local modules.

Note: I’ve omitted any namespaces, but for completeness of this post, a name space would be added as the first line in the module files (if required) as per

namespace MyNamespace

module MyModule =
   let square x = x * x

The top-level module

The top-level module is basically a module which contains all the code for an application and it has slightly different rules regarding it’s layout compared to the local modules (see Modules (F#).

Reproducing a little from the above link we see that a top-level module does not need an = sign at the end of the module name and declarations need not be indented, for example the following is perfectly acceptable in a top-level module but not a local module

module MyModule

let hello = 
   printfn "Hello"

Local Modules

Local modules are basically re-usable files. The usual usage would be to group together related code. Unlike the top-level module, local modules require indented formatting as well as an = after the module name, so the previously define code for a top-level module would look like the following code in a local module

module MyModule =

   let hello =
      printfn "Hello"

The Program/EntryPoint module

By default the code generated by Visual Studio as the starting point for an F# applications looks like

[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    0 // return an integer exit code

But implicitly this will be compiled as

module Program
[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    0 // return an integer exit code

Thus conversely the module name of a top-level module can be omitted if it’s the only file in the application.

Inner Modules

Not only can a file be declared as a module but you can also have modules nested within modules, for example

module GrandParent =
   module Parent =
      module Child =
         let x = 100

Within a top-level module we can define this as

module GrandParent

module Parent =
   module Child =
      let x = 100

in other words the top level module does not need the = sign or the indenting of the Parent module.

How to use a module

So we’ve shown how to declare modules but at some point we need to use them, to achieve this we use the following

open MyModule

If we’d had a namespace we could open the namespace such as open MyNamespace. In such a case where modules were in the namespace we could prefix them on the functions, such as MyModule.square 3. Alternatively we could open the namespace and specific module(s) such as open MyNamespace.MyModule and thus have no need to prefix the functions with the module name.

[<EntryPoint>] into F#

The entry point to an F# application is declared using the attribute [<EntryPoint>]. For example, the default code when creating an F# application looks like

[<EntryPoint>]
let main argv = 
    printfn "%A" argv
    0 // return an integer exit code

This declares that the function “main” is the entry point into the application.

This is fine until you start adding modules (new source code files in F#). So if we now add a new item (F# source file) to an F# application you’ll see an error such as this

Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. ‘namespace SomeNamespace.SubNamespace’ or ‘module SomeNamespace.SomeModule’. Only the last source file of an application may omit such a declaration.

To fix this we need to do two things. The first is that by default the new module simple gets created with the following (obviously the module name will be the same as the filename you supplied it with)

module MyModule

as the error suggests we need to create a namespace for the new module, so for example

namespace Samples.One

module Samples =
   let helloWorld =
      printfn "Hello World"

However this only solves part of the problem – the namespace issue.

The next thing we need to do is rather strange to me (maybe it’s my C++ background). But the [<EntryPoint>] file needs to be the last source code file in the project.

To make this happen, right mouse click on the Program.fs file (or whatever the name of your[<EntryPoint>] file is and using the Move Down and/or Move Up menu items, move the position of the file in the project to be the last source code file (note: it needn’t be the last actual file just the last source code file).

Note: Basically the order of the source code files is the order they’re compiled. So ordering of the files in important in F#.

MVVM Cross – Getting Started

As the primary aim of MVVM cross is to supply a cross platform MVVM framework, our primary goal must be to try to ensure that all cross platform compatible code is separated from non-cross platform. Ideally all non-UI code would be cross platform in a perfect world.

So this and any other posts on MVVM cross will assume and aim to ensure that the non-UI code is as portable as possible between platforms. The example code etc. will assume that Xamarin tools have been installed in Visual Studio, but this is not a requirement for the examples to work.

Creating the view model

  1. So to begin with we need to create a PCL (Portable Class Library). Give the project a name (i.e. I named mine Common) and then press OK, then select all the platforms you want the library to be compatible with – as I have Xamarin tools for Visual Studio installed the selected platforms include Windows, Windows 8, Windows Phone 8, Xamarin.Android and Xamarin.iOS
  2. Delete Class1.cs as we’re not going to be needing it
  3. Using NuGet, add MVVM cross to the project
  4. Now, MVVM cross uses IoC and a naming based convention approach to wiring views and view models together, so you’ll notice that by default NuGet created a ViewModels folder with a FirstViewModel.cs. Whilst you can move the location or change the namespace of the view model file, it’s name and that of the corresponding view need to map to one another. Like Caliburn Micro a XXXViewModel is mapped to an XXXView.
  5. For this sample we’ll implement the FirstViewModel implemented in Stuart Lodge’s N+1 youtube video on using MVVM cross. So edit the FirstViewModel to look like the following
    public class FirstViewModel : MvxViewModel
    {
       private string firstName;
       private string lastName;
    
       public string FirstName
       {
          get { return firstName; }
          set
          {
             firstName = value; 
             RaisePropertyChanged(() => FirstName);
             RaisePropertyChanged(() => FullName);
          }
       }
    
       public string LastName
       {
          get { return lastName; }
          set
          {
             lastName = value;
             RaisePropertyChanged(() => LastName);
             RaisePropertyChanged(() => FullName);
          }
       }
    
       public string FullName
       {
          get { return String.Format("{0} {1}", firstName, lastName); }
       }
    }
    

    Note: Our view model inherits from MvxViewModel

And that’s it for now.

So to review the above, we create a PCL library, add the MVVM cross assemblies (in this case we used NuGet), derive any view models from MvxViewModel and we’re done.

Note however that we kept the default FirstViewModel class, had we changed this name we’d also need to change the code in App.cs to reflect this change. The view model we created is basically the app view model so it’s registered in the App.cs file. But you’d get a compile time error if you didn’t make this change so that’s easy to fix.

Creating the view

Whilst it’s probably more interesting to now create an iOS or Windows Phone 8 app. I want to start with a WPF application, so here’s the process for creating a WPF app and connecting it to our view model.

  1. Create a new WPF Application project (I’m using the same solution as my PCL project created above)
  2. I’m set this project as the start StartUp project
  3. Using NuGet add MVVM cross to the references
  4. Add a reference to our PCL project
  5. Now remember that the view and view model are mapped by a naming convention, so in the Views folder you should find FirstView.xaml. Notice the view is an MvxWpfView, so similarly new views should also be derived from this class.
  6. Again, as per Stuart Lodge’s N+1 video we’ll simply add the following to the XAML for the FirstView.xaml
    <TextBox Text="{Binding FirstName, Mode=TwoWay}"/>
    <TextBox Text="{Binding LastName, Mode=TwoWay}"/>
    <TextBlock Text="{Binding FullName, Mode=OneWay}"/>
    
  7. Finally and before we can run this code. I named my PCL assembly Common and thus we need to change the Setup.cs file to reflect this. the method CreateApp needs to look like this

    protected override IMvxApplication CreateApp()
    {
       // uses the App object in our PCL assembly
       return new Common.App();
    }
    

Now this should run – no need to assign any views to the MainWindow, MVVM cross will handle this for you based upon your App class in the PCL assembly.

Indexing your MongoDB data

By default MongoDB creates an index on the _id (ObjectId) field, but we can easily add indexes to other fields.

Using the JavaScript shell

In the JavaScript shell simply call ensureIndexUsing the 10gen drivers in C#

In C# using the 10gen drivers we can create an index using the following

collection.EnsureIndex(new IndexKeysBuilder().Ascending("artist"));

where collection is

MongoCollection<CD> collection = db.GetCollection<CD>("cds");

To remove an index we can simply use

collection.DropIndex(new IndexKeysBuilder().Ascending("Artist"));

Handling case-sensitive mapping from MongoDB to a POCO

So the convention appears to be to use camel case for column/field names within MongoDB. For example if we create an entry such as db.cds.Update({artist:”Alice Cooper”}).

In C# the convention is for properties, for example, to be written in Pascal case. So we’d have something like

public class CD
{
   public ObjectId Id { get; set; }
   public string Artist { get; set; }
   public string Title { get; set; }
   public string Category { get; set; }
}

So obviously MongoDB has a field name artist and we need to map it to the property name “Artist”.

To handle this we can use the BsonElement in the MongoDB.Bson.Serialization.Attributes namespace, as per

public class CD
{
   public ObjectId Id { get; set; }
   [BsonElement("artist")]
   public string Artist { get; set; }
   [BsonElement("title")]
   public string Title { get; set; }
   [BsonElement("category")]
   public string Category { get; set; }
}

or we can set up the mappings using the following

BsonClassMap.RegisterClassMap<CD>(cm =>
{
   cm.AutoMap();
   cm.GetMemberMap(c => c.Artist).SetElementName("artist");
   cm.GetMemberMap(c => c.Title).SetElementName("title");
   cm.GetMemberMap(c => c.Category).SetElementName("category");
});

Note: we do not need to setup the Id field to any mapping as this appears to be mapped based upon it’s type.

A class map may only be registered once, we can use BsonClassMap.IsClassMapRegistered if need be to ensure this.

More information can be found at Serialize Documents with the CSharp Driver

Starting out with MongoDB

This is a post on some of the basics of using MongoDB (on Windows).

mongod.exe

So to run the mongo server we use mongod.exe, if all goes well the server will start up and state it’s waiting for connections.

mongo.exe

The JavaScript shell used as the client admin application for the mongo server is named mongo.exe.

Shell Commands

  1. use <database> is used to switch the shell to using the named <database>. If this command is not used, be default the test database will be used.
  2. show dbs can be used to get a list of all the databases stored in the instance of MongoDB.
  3. show collections lists the available collections within the selected database. This is analogous to listing the tables in an SQL database.
  4. show users lists the users added to the database. To add a user via the JavaScript Shell we can use the following
    db.addUser({user: "UserName", pwd: "Password", roles: ["readWrite", "dbAdmin"]})
    

    Beware, as the roles are not validated against any schema or role list, so you can assign roles names which are not recognised as specific mongo roles, i.e. I made a typo for dbAdmin and it’s accepted as a role.

  5. db is the database object, so we can execute commands such as db.stats()
  6. db.myobjects let’s assume we created a database and added some objects into a collection named myobjects. Because we’re using a JavaScript shell we can access the myobjects collection off of the db object. So for example we can now using db.myobjects.count() to get a count of the number of “rows” in the collection. Equally we can use commands such as db.myobjects.find() to list the rows in the collection.

Example workflow

This is a simple example of using mongo.exe to create a database and some data, then querying the database.

For this example we’ll create a CD database which will be used to contain information on all the CD’s we own.

  1. If it’s not already running, run mongod.exe
  2. In a separate command prompt, run mongo.exe
  3. We’ll create the database by typing use CDDatabase, remember it will not be fully created until some data is added to it
  4. We can check which database we’re currently viewing by typing db. This will show us we’re in the CDDatabase, but if you now type show dbs you’ll notice the database still doesn’t actually exist in the list of available databases
  5. We can now create our first entry in the database. Notice, unlike an SQL database we do not create tables etc. So to create an entry we can type the following
    a = {artist:"Alice Cooper", title:"Billion Dollar Babies", category:"Rock"}
    db.cds.insert(a)
    

    Note: we don’t need to create a variable as we’ve done here, we can just replace ‘a’ in the insert method with the right hand side of the = operator as per

    db.cds.insert({artist:"Alice Cooper", title:"Billion Dollar Babies", category:"Rock"})
    

    So we should have now successfully added an entry into the “cds” collection. Notice again we do not need to define the “cds” collection first, it’s dynamically created when we start using it.

    We can use the command show collections to display a list of the collections that make up the datavase.

    Feel free to add more data if you wish.

  6. Let’s now see what’s in the collection dbs. To do this simply type db.cds.find(). You should now see all the entries within the “cds” collection that you created. Notice that a variable _id of type ObjectId has been added to our data.

    To find a single entry, in this example we’ll find the artist by name we simply use db.cds.find({artist:”Alice Cooper”})

  7. So as part of the standard CRUD operations on data, we’ve seen how to Create and Read data, now let’s look at updating data. Run the following command
    db.cds.insert({artist:"Iron Maiden", title:"Blood Brothers"})
    

    Now I’m left off the category here, so we now need to update this entry. We use the collection’s update method, thus

    db.cds.update({artist:"Iron Maiden"}, {$set:{category:"Heavy Metal"}})
    

    The first argument in the update method {artist:”Iron Maiden”} is the query string, in other words update where artist is “Iron Maiden”. The second argument is the update action, which simply tells update to set the category to “Heavy Metal”.

    If we run this command we’ll see the category added, but this command works only on the first item found, so if there were multiple “Iron Maiden” entries missing the category this would be a bit of a problem. However we can apply a third argument to update to solve this.

    db.cds.update({category:"Rock"}, {$set:{category:"Heavy Rock"}},{multi:true})
    

    The addition of {multi:true} will allow the update to be applied to all matching entries.

  8. Now to the final CRUD operation – Delete. This is simply a case of using the collection’s remove method. For example
    db.cds.remove({artist:"Alice Cooper"})
    

    Be careful not to forget the query part of this method call, the {artist:”Alice Cooper”} as using db.cds.remove() will remove all entries from the collection.