Phillip Trelford's Array

POKE 36879,255

Connect All The Things – MVP Summit 2013

On Tuesday I did a lightning talk at the MVP Summit in Bellevue on connecting to all things, from statistics to statistical programming languages with Intellisense and LINQ using F# Type Providers, a feature shipped with Visual Studio 2012:


 

Connecting to an Excel file:

Excel Provider

Querying users stored on SQL Azure:

query {
  for u in db.Users do
  where (u.UserId <> userId)
  select u
}

Querying genres via the Netflix API:

query {
    for g in ctx.Genres do
    where (g.Name = genre)
    for t in g.Titles do
    where (t.ReleaseYear ?<= 1959)
    where (t.ReleaseYear ?>= 1934)
    sortByNullable t.AverageRating
    skip nToSkip
    take nToTake
    select t
}

Running B-Movie Sample on Azure: b-movies.azurewebsites.net

Connecting to the World Bank:

type WorldBank = WorldBankDataProvider<"World Development Indicators">
let data = WorldBank.GetDataContext()

let countries () = 
 [| data.Countries.India        
    data.Countries.``United Kingdom``
    data.Countries.``United States`` |]

Rendering charts asynchronously using JavaScript High Charts using TypeScript definitions:

let render () = async {
 let opts = h.HighchartsOptions() 
 opts.chart <- h.HighchartsChartOptions(renderTo = "chart", ``type`` = "line")
 opts.title <- h.HighchartsTitleOptions(text = "School enrollment")

Running in the browser using FunScript (F# to JavaScript compiler):

Charting World Bank

Querying Hadoop Hive in the browser:

query {
 for i in hive.iris do
 groupBy i.``class`` into g
 select (g.Key, Seq.length g) 
}

 

Iris data

Mocking with Foq

Foq is an open source .Net mocking library with a familiar fluent API for Moq users that lets you setup mock object using either LINQ or F# Code Quotations. Moq was developed to take advantage of .Net 3.5 LINQ expression trees and C# 3.0 features. Foq has been designed to provide first-class support for users of both C# and F#. C# users can use the LINQ API while F# users can choose between the LINQ API and Code Quotations. We use F# as a unit testing language at work and Foq for mocking code written in both C# and F#.

Examples

Setup a mock method in C# with a lambda expression:

new Mock<IList<int>>()
    .SetupFunc(x => x.Contains(It.IsAny<int>())).Returns(true)
    .Create();

Setup a mock method in F# with a Code Quotation:

Mock<System.Collections.IList>()
    .Setup(fun x -> <@ x.Contains(any()) @>).Returns(true)
    .Create()

Setup a property in C# with a lambda expression:

new Mock<IList<int>>()
    .SetupPropertyGet(x => x.Count).Returns(1)
    .Create();

Setup multiple properties in C# with an anonymous object:

new Mock<IOrder>()
    .SetupProperties(new {
        Price = 99.99M,
        Quantity = 10,
        Side = Side.Bid,
        TimeInForce = TimeInForce.GoodTillCancel
    })
.Create();

Setup multiple members in F# with a Code Quotation:

Mock<IList<char>>.With(fun xs ->
    <@ xs.Count --> 2 
        xs.Item(0) --> '0'
        xs.Item(1) --> '1'
        xs.Contains(any()) --> true
        xs.RemoveAt(2) ==> System.ArgumentOutOfRangeException()
    @>
)

Verify a method was called in C#:

Mock.VerifyFunc(() => list.Contains(1));

Verify a method was called once in F#:

Mock.Verify(<@ xs.Contains(any()) @>, once)

Download

Foq is available on Nuget or for F# projects you can just include the Foq.fs source file.

Moq with F# 3

F# 3 has LINQ expression support built-in just like C# and VB.Net. Prior to this basic LINQ expression interop could be achieved with the F# PowerPack and F# Code Quotations.

F# 3 LINQ support opens up APIs that use LINQ expressions like Moq, a popular .Net mocking library. With some minor workarounds Moq is relatively easy to call from F#.

C# Moq example:

var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);

F# requires a type annotation:

TypeAnnotation

F# requires the return value to be explicitly ignored:

UseIgnore

F# Moq example with required type annotation and return value piped to ignore:

let mock = Mock<IFoo>()
mock.Setup<bool>(fun foo -> foo.DoSomething("ping")).Returns(true) |> ignore

The type annotation is required as the Setup method provides multiple overloads with differing generic parameters. Another way to workaround this is to write specific extension methods for overloads:

type Moq.Mock<'T> when 'T : not struct with
  /// Specifies a setup on the mocked type for a call to a function
  member mock.SetupFunc<'TResult>(expression:Expression<Func<'T,'TResult>>) =
    mock.Setup<'TResult>(expression)
  /// Specifies a setup on the mocked type for a call to a void method
  member mock.SetupAction(expression:Expression<Action<'T>>) = 
    mock.Setup(expression)
  /// Specifies a setup on the mocked type for a call to a property setter
  member mock.SetupSetAction<'TProperty>(setupExpression:Action<'T>) 
    : Moq.Language.Flow.ISetupSetter<'T,'TProperty> = 
    mock.SetupSet<'TProperty>(setupExpression)

The ignore statement is required as F# requires return values to be handled explicitly. Moq’s fluent inteface provides some methods where the return value is ignorable.

The issues using Moq’s API from F# 3 can be fairly easily worked around. That said for an API designed specifically for F# consider using Foq which has similar functionality to Moq and supports both Code Quotations and LINQ expressions. You may also find F#’s built-in Object Expressions sufficient for many tasks.