Showing posts with label F#. Show all posts
Showing posts with label F#. Show all posts

Tuesday, May 13, 2014

Mapping objects to JSON with Fleece

In the last post I briefly explained some of the consequences of breaking parametricity, in particular for JSON serialization. I used JSON serialization here as a particular case only to introduce Fleece, but breaking parametricity anywhere has similar consequences.

So how can we serialize JSON without breaking parametricity?

The simplest thing we could do is to write multiple monomorphic Serialize functions, one for each type we want to serialize, e.g:

class Person {
    public readonly int Id;
    public readonly string Name;

    public Person(int id, string name) {
        Id = id;
        Name = name;
    }
}

string Serialize(Person p) {
    return @"{""Id"": " + p.Id + @", ""Name"": """ + p.Name + @"""}";
}

You’ll notice that this code doesn’t escape the Name value and therefore will generate broken JSON in general. Why doesn’t this happen with the Id? Types! The lowly int type has restricted the values it can have and therefore we can statically assure that it doesn’t need any escaping. Cool, huh?

So how do we solve the escaping problem for the Name field? With more types, of course! Instead of handling JSON as strings, we create some types to model more precisely what JSON can do, and let the compiler check that for us. System.Json does just that, so let’s use it. Strictly speaking it’s still a too loose but it’s decent enough. Our code becomes:

JsonObject Serialize(Person p) {
    return new JsonObject {
        {"Id", p.Id},
        {"Name", p.Name},
    };
}

Now we don’t have to worry about encoding issues, JsonObject takes care of that. Also the function now returns a JsonObject instead of a string, which allows us to safely compose the result into larger JSON objects. When we’re done composing, we call ToString() to get the serialized JSON.
One way to look at this is that we’re defining a tiny language here, with JsonValue.ToString() being one possible interpreter.
I’m sorry if these explanations sound a bit patronizing, but I really want to emphasize how types make our job easier.

Let’s raise the abstraction bar a bit and write a function that serializes an IEnumerable<T>. Since we don’t want to break parametricity, we must ensure that this will work for any type T such that T can itself be serialized. But we don’t know how to turn any arbitrary type T into a JsonValue, and we’ve ruled out runtime type inspection, so we have to pass the conversion explicitly:

JsonArray Serialize<T>(IEnumerable<T> list, Func<T, JsonValue> serializerT) {
    return new JsonArray(list.Select(serializerT));
}

That works, but it’s not very nice. We have to compose these serializer functions manually! Every time we want to serialize an IEnumerable<T> we’ll have to look up where the function to serialize T is. Is there any way to avoid that?

We could pass the conversion by using interfaces. If we have:

public interface IToJson {
    JsonValue ToJson();
}

We could make Person implement IToJson simply by moving the Serialize(Person p) function above to the definition of Person:

class Person: IToJson {
    public readonly int Id;
    public readonly string Name;

    public Person2(int id, string name) {
        Id = id;
        Name = name;
    }

    public JsonValue ToJson() {
        return new JsonObject {
            {"Id", Id},
            {"Name", Name},
        };
    }
}

Then serializing a list can be restricted to types implementing IToJson:

JsonValue ToJson<T>(this IEnumerable<T> list) where T: IToJson {
    return new JsonArray(list.Select(x => x.ToJson()));
}

But this only works for types we control. We can’t make IEnumerable<T> implement IToJson. We can wrap it:

class JsonList<T>: IToJson where T: IToJson {
    public readonly IEnumerable<T> List;

    public JsonList(IEnumerable<T> list) {
        List = list;
    }

    public JsonValue ToJson() {
        return new JsonArray(List.Select(x => x.ToJson()));
    }
}

But this is inconvenient. Suppose we have a class Company with a list of Person as employees. Here’s how serialization would look like:

class Company: IToJson {
    public readonly string Name;
    public readonly List<Person> Employees;

    public Company(string name, List<Person> employees) {
        Name = name;
        Employees = employees;
    }

    public JsonValue ToJson() {
        return new JsonObject {
            {"Name", Name},
            {"Employees", new JsonList<Person>(Employees).ToJson()}
        };
    }
}

That’s not much better than manually inlining the code for JsonList.ToJson(). Ideally, we just want to call a simple function ToJson and have the compiler somehow figure out if there’s a suitable function declared for the type of the argument. Overloading would be great if the generic ToJson function for lists could somehow recursively look into what overloads are defined if there’s a match for T, at compile time.

As far as I know C# can’t do that but it turns out that F# can.

Enter Fleece

With Fleece, converting Person and Company to JSON goes like this, without implementing any IToJson interface:

type Person with
   static member ToJSON (x: Person) =
       jobj [ 
           "Id" .= x.Id
           "Name" .= x.Name
       ]

type Company with
    static member ToJSON (x: Company) =
        jobj [
            "Name" .= x.Name
            "Employees" .= x.Employees
        ]

let company = { Company.Name = "Double Fine"; Employees = [{ Employee.Id = 1; Name = "Tim Schafer"}] }

let jsonAsString = (toJSON company).ToString()

Fleece here is statically ensuring that the type of the argument of toJSON has a definition of a static member ToJSON. It also checks statically that every type to the right of a .= expression has a suitable definition of ToJSON, and chooses it automatically. If there isn’t a suitable definition, you get a compile-time error.

Moreover, it "composes" (probably not the right term to use here) the serializers automatically at compile-time. In previous examples, we had to compose the list serializer with the Person serializer “manually” to serialize a concrete list of persons. Fleece defines a parametric serializer for lists, and then the compiler composes this serializer with the serializer for Person we have defined here.

What makes this possible in F# are inlines and static member constraints. Here’s how the definition of ToJSON for a list looks like:

type ToJSONClass with
    static member inline ToJSON (x: 'a list) =
        JArray (listAsReadOnly (List.map toJSON x))

If you hover in Visual Studio over the ToJSON keyword in this definition, it says ToJSON: 'a list -> JsonValue (requires member ToJSON). This means that F# is inferring that the type 'a must have a ToJSON member in order to call toJSON on a list of 'a.

This is equivalent to Haskell’s:

instance (ToJSON a) => ToJSON [a] where
   toJSON = Array . V.fromList . map toJSON

Haskell has dedicated syntax for this which makes the constraint explicit compared to F#.

This has long been used in F# for generic math. F# also has an ad-hoc, limited form of this in the EqualityConditionalOn attribute, where the equality of a type depends on a type argument having “equality”. So for example, this in F#:

type MyBox<[<EqualityConditionalOn>] 'a> = ...

Roughly corresponds to Haskell’s:

instance (Eq a) => Eq (MyBox a) where ...

With the difference that F# can sometimes derive equality automatically depending on the equality of type arguments.

The bottom line here is that the toJSON function is overloaded only for supported types, instead of being parametrically polymorphic, so it does not break parametricity. This overloading is also called ad-hoc polymorphism. Haskell achieves ad-hoc polymorphism thanks to typeclasses, and this technique is based on that. In fact, Fleece is based on Aeson, the de-facto standard JSON library for Haskell.

Anton Tayanovskyy had also prototyped a similar typeclass-based JSON library for F# some time ago.

Fleece only scratches the surface of what’s possible with inline-encoded typeclasses (a.k.a. “type methods”). I recommend reading Gustavo León’s blog to learn more about this technique and checking out the FsControl and FSharpPlus projects.

Refactor safety

Now, in my last post I claimed that this approach would save code by saving tests. But here we see that we have to write serializer code for each type that we want to serialize, unlike reflection-based libraries! That’s quite a bit of boilerplate! I could argue that it’s a small price to pay to get code you can reason about, but the truth is this is pretty trivial code that could be easily generated at compile-time.
In fact, Haskell can do that, either with Template Haskell or the more recent GHC.Generics, in which case you only need to make your type derive Generic and declare the typeclass instance. The actual serialization code is filled in by the compiler.

But there is a bigger problem with both reflection- and GHC.Generics-derived serialization: they tie JSON output to identifiers in your code. So whenever you rename some identifier (for example a field name in a record) in a type that is used to model some JSON output, you’re implicitly changing your JSON schema. You’re making a breaking change in the output of the program in what’s normally a safe operation. To quote a tweet:

Or more bluntly:

Still, it might be useful to start prototyping with reflection-based serializer while being aware of these issues, then switch to explicit serialization once the initial prototype stage is done. Some haskellers do this with GHC.Generics-derived serialization (thanks to Jonathan Fischoff for confirming this on #haskell IRC).

Even in C#, without these F# fake typeclases, you should be very wary of breaking parametricity and the cost on maintenance it implies. In my opinion, the boilerplate is worth it to avoid breaking parametricity.

In the next post we’ll see how to use Fleece to map in the opposite direction: JSON to objects. We’ll also see some of the drawbacks of these fake typeclasses.

Tuesday, August 7, 2012

Optional parameters interop: C# - F#

Both C# and F# support optional parameters. But since they're implemented differently, how well do they play together? How well do they interop?

Here's I'll analize both scenarios: consuming F# optional parameters from C#, and consuming C# optional parameters from F#.

For reference, I'm using VS2012 RC (F# 3.0, C# 5.0)

Calling C# optional parameters in F#

Let's start with some C# code that has optional parameters and see how it behaves in F#:

public class CSharp {
    public static string Something(string a, int b = 1, double c = 2.0) {
        return string.Format("{0}: {1} {2}", a, b, c);
    }
}

Here are some example uses of this function:

var a = CSharp.Something("hello");
var b = CSharp.Something("hello", 2);
var c = CSharp.Something("hello", 2, 3.4);

Now we try to call this method from F# and we see:

csharp-optional

Uh-oh, those parameters sure don't look very optional. However, it all works fine and we can write:

let a = CSharp.Something("hello")
let b = CSharp.Something("hello", 2)
let c = CSharp.Something("hello", 2, 3.4)

which compiles and works as expected.

Calling F# optional parameters in C#

Now the other way around, a method defined in F#, using the F# flavor of optional parameters:

type FSharp = 
    static member Something(a, ?b, ?c) = 
        let b = defaultArg b 0 
        let c = defaultArg c 0.0 
        sprintf "%s: %d %f" a b c 

We can happily use it like this in F#:

let a = FSharp.Something("hello")
let b = FSharp.Something("hello", 2)
let c = FSharp.Something("hello", 2, 3.4)

But here's how this method looks like in C#:

fsharp-to-csharp

Yeah, there's nothing optional about those parameters.

What we need to do is to implement the C# flavor of optional parameters "manually". Fortunately that's pretty easy, just mark those parameters with the Optional and DefaultParameterValue attributes:

open System.Runtime.InteropServices

type FSharp = 
    static member Something(a, [<Optional;DefaultParameterValue(null)>] ?b, [<Optional;DefaultParameterValue(null)>] ?c) = 
        let b = defaultArg b 0 
        let c = defaultArg c 0.0 
        sprintf "%s: %d %f" a b c 

Why "null" you ask? The default value should have been None, but that's not a compile-time constant so it can't be used as an attribute argument. Null is interpreted as None.

These attributes don't affect F# callers, but now in C# we can write:

Console.WriteLine(FSharp.Something("hello"));
Console.WriteLine(FSharp.Something("hello", FSharpOption<int>.Some(5)));

So we have optional parameters but we still have to deal with option types when we want to use them. If you find that annoying or ugly, you could use FSharpx, in which case FSharpOption<int>.Some(5) turns into 5.Some() .

The astute reader will suggest an overload just to handle the C# compatibility case. Alas, that doesn't work in the general case. Let's try and see what happens:

type FSharp = 
    static member private theActualFunction (a, b, c) =
        sprintf "%s: %d %f" a b c

    static member Something(a, ?b, ?c) =
        let b = defaultArg b 0
        let c = defaultArg c 0.0
        FSharp.theActualFunction(a,b,c)

    static member Something(a, [<Optional;DefaultParameterValue(0)>] b, [<Optional;DefaultParameterValue(0.0)>] c) =
        FSharp.theActualFunction(a,b,c)

Note that I moved the "actual working function" to a separate method, otherwise the second overload would just recurse. But we have a duplication in the definition of the default values. Still, the real problem shows when we try to use this in F#:

let d = FSharp.Something("hello", 2, 3.4)

This doesn't compile as F# can't figure out which one of the overloads to use.

Conclusion

F# has no issues consuming optional parameters defined in C#.

When writing methods with optional parameters in F# to be called from C#, either add the corresponding attributes and deal with the option types, or add a separate non-overloaded method. Or forget the optional parameters altogether and add overloads, just as we all did in C# before it supported optional parameters.

Monday, July 30, 2012

A tale of equational reasoning in F#

My implementation of formlets, based on the original paper, composes quite a few applicative functors. They're all standard applicatives. For example, the one that looks up values from the submitted form is just a specialized Reader (i.e. a Reader with one of the type parameters fixed to the form type). The applicative responsible for generating form element names is a State. Another two of the applicatives are actually the same applicative, only specialized with different type parameters.

Since many of these are already implemented in FSharpx, I decided to use those implementations instead... After making the necessary changes and getting it to compile, I ran the tests and got a lot of failures. Many of the outputs involving lists were exactly in inverse order! I traced it down to the composition of applicatives, but I couldn't figure out what was wrong.

I'll illustrate with a simple but concrete example. We'll use the Writer applicative. Essentially, the effect of this applicative is appending values with a monoid. Here we'll just accumulate on a list.

This is much simpler to see in code:

let puree x = [],x 
let ap (x1,x2) (f1,f2) = f1 @ x1, f2 x2 

An example using it:

puree (-) |> ap (["a";"b"],3) |> ap (["c";"d"],2)

This evaluates to (["a"; "b"; "c"; "d"], 1) , i.e. it concatenates the lists (the effect) and applies the function to the second value in the tuple.

So far so good. Now let's try to compose this applicative with itself. Composing applicatives is easy: as I explained in a previous article, just lift ap and apply pure to pure:

let lift2 f a b = puree f |> ap a |> ap b

let composedPure x = x |> puree |> puree 
let composedAp x f = lift2 ap x f

Let's see how this works:

composedPure (-) 
|> composedAp (["a"; "b"], ([1; 2], 2)) 
|> composedAp (["c"; "d"], ([3; 4], 3))

which gives us (["c"; "d"; "a"; "b"], ([1; 2; 3; 4], -1))

Uh oh, the outer applicative has its effect flipped! The result should have been (["a"; "b"; "c"; "d"], ([1; 2; 3; 4], -1)) . What went wrong here?

One difference in this code with the Haskell definition of applicative functors is that I flipped the parameters of ap. This allowed us to apply ap with a pipe as is usual in F#. You could also use a forward and a backward pipe to "infixify" a function but it just doesn't look right to me. Even though it compiles and apparently looks correct, this difference broke our applicative composition.

In order to fix the applicative composition and still keep the convenient flipped parameters, we have to change composedAp to:

let flip f a b = f b a

let composedAp x f = flip (lift2 (flip ap)) x f

The question now is: do you really understand why this composedAp is correct, just by looking at its definition, while the previous one would flip one of the applicatives and not the other?

To be honest, I don't. But simple equational reasoning can tell us what went wrong. Let's start with the original (incorrect) definition of composedAp:

  lift2 ap x f 
= puree ap |> ap x |> ap f              // lift2 definition
= ap f (ap x (puree ap))                // |> definition
= ap (f1,f2) (ap (x1,x2) (pap1, pap2))  // expand tuples, apply puree
= ap (f1,f2) (pap1 @ x1, pap2 x2)       // apply inner ap
= pap1 @ x1 @ f1, pap2 x2 f2            // apply outer ap
= [] @ x1 @ f1, ap x2 f2                // apply puree
= x1 @ f1, ap (x21, x22) (f21, f22)     // simplify empty list, expand tuples
= x1 @ f1, (f21 @ x21, f22 x22)         // apply ap

Now the correct composedAp, for comparison:

flip (lift2 (flip ap)) x f 
= flip (fun f a b -> ap b (ap a (puree (flip ap)))) x f     // lift2 definition
= (fun f a b -> ap b (ap a (puree (flip ap)))) f x          // apply flip
= ap x (ap f (puree (flip ap)))                             // apply lambda
= ap (x1,x2) (ap (f1,f2) (pfap1, pfap2))                    // expand tuples, apply puree
= ap (x1,x2) (pfap1 @ f1, pfap2 f2)                         // apply ap
= pfap1 @ f1 @ x1, pfap2 f2 x2                              // apply ap
= [] @ f1 @ x1, (flip ap) f2 x2                             // puree
= f1 @ x1, ap x2 f2                                         // simplify empty list, apply flip
= f1 @ x1, ap (x21, x22) (f21, f22)                         // expand tuples
= f1 @ x1, (f21 @ x21, f22 x22)                             // apply ap

By comparing both you can get a better understanding of why two flips are necessary.

Reasoning like this is a simple but powerful tool. We kinda do it continuously, informally, while writing code, which is usually called "running the program in your head". The absence of side-effects (i.e. pure functional programming) makes it easier to do it formally as well as informally, since you typically need to juggle less stuff in your head.

Monday, June 11, 2012

Fuchu: a functional test library for .NET

In my last two posts I showed how MbUnit supports first-class tests, and how you could use that to build a DSL in F# around it.

I explained how many concepts in typical xUnit frameworks can be more simply expressed when tests are first-class values, which is not the case for most .NET and Java test frameworks.

More concretely, test setup/teardown is a function over a test, and parameterized tests are... just data manipulation.

Since first-class tests greatly simplify things, why not dispense with the typical class-based, attribute-driven approach and build a test library around first-class tests? Well, Haskellers have been doing this for at least 10 years now, with HUnit.

HUnit organizes tests using this tree:

-- | The basic structure used to create an annotated tree of test cases. 
data Test 
    -- | A single, independent test case composed. 
    = TestCase Assertion 
    -- | A set of @Test@s sharing the same level in the hierarchy. 
    | TestList [Test] 
    -- | A name or description for a subtree of the @Test@s. 
    | TestLabel String Test 

Where Assertion is simply an alias for IO (). This is all you need to organize tests in suites and give them names.

We can trivially translate this to F# :

type TestCode = unit -> unit

type Test = 
    | TestCase of TestCode
    | TestList of Test seq
    | TestLabel of string * Test

Let's see an example:

let testA = 
    TestLabel ("testsuite A", TestList 
                         [
                            TestLabel ("test A", TestCase(fun _ -> Assert.AreEqual(4, 2+2)))
                            TestLabel ("test B", TestCase(fun _ -> Assert.AreEqual(8, 4+4)))
                         ])

It's quite verbose, but we can define the same DSL as I defined earlier for MbUnit tests, so this becomes:

let testA = 
    "testsuite A " =>> [
        "test A" => 
            fun _ -> Assert.AreEqual(4, 2+2)
        "test B" =>
            fun _ -> Assert.AreEqual(8, 4+4)
    ]

Actually, I first ported HUnit (including this DSL), then discovered that MbUnit has first-class tests and later wrote the DSL around MbUnit. Everything I described in those posts (setup/teardown as higher-order functions, parameterized tests as simple data manipulation, arbitrary nesting of test suites) applies here in the exact same way.

In fact, MbUnit's class hierarchy of Test/TestSuite/TestCase can be read as the following algebraic data type:

type Test =
| TestSuite of string * Test list
| TestCase of string * Action

which turns out to be very similar to the tree we translated from HUnit, only the names are embedded instead of being a separate case.

I called this HUnit port Fuchu (it doesn't mean anything), it's on github.

Assertions

Fuchu doesn't include any assertion functions, or at least not yet. (EDIT: assertions were added in 0.2.0) It only gives you tools to organize and run tests, but you're free to use NUnit, MbUnit, xUnit, NHamcrest, etc, or more F#-ish solutions like Unquote or FsUnit or NaturalSpec for assertions.

Tighter integration with FsCheck is planned. (EDIT: it was added in the first release of Fuchu)

Runner/Tooling

As with HUnit, the test assembly is the runner itself. That is, as opposed to having an external test runner as with most test frameworks, your test assembly is an executable (a console application). This is because it's more of a library instead of a framework. As a consequence, there is no need of installing any external tool to run tests (just hit CTRL-F5 in Visual Studio) or debug tests (just set your breakpoints and hit F5 in Visual Studio). Here's a clear signal of why this matters:

So how do you run tests with Fuchu? Given a test suite testA like the one defined above, you can run it like this:

[<EntryPoint>]
let main _ = run testA // or runParallel

But this is quite inconvenient, as it's common to split tests among different modules/files and this would mean having to list all tests somewhere, to feed them to the run function. HUnit works around this using Template Haskell, and OUnit (OCaml's port of HUnit) users generate the boilerplate code by parsing the tests' source code.

In .NET we can just decorate the tests with an attribute and then use reflection to fetch them:

[<Tests>]
let testA = 
    "2+2=4" => 
        fun _ -> Assert.AreEqual(4, 2+2)

[<Tests>]
let testB = 
    "2*3=6" => 
        fun _ -> Assert.AreEqual(7, 2*3)
[<EntryPoint>]
let main args = defaultMainThisAssembly args

This function defaultMainThisAssembly does exactly what it says on the tin. Notice that it also takes the command-line args, so if you call it with "/m" it will run the tests in parallel. (Curiously, you can't say let main = defaultMainThisAssembly, it won't be recognized as the entry point).

By the way, this is just an example, you wouldn't normally annotate every single test with the Tests attribute, only the top-level test group per module.

Run this code and you get an output like this:

2*3=6: Failed: 
  Expected: 7
  But was:  6

  G:\prg\Test.fs(15,1): SomeModule.testB@15.Invoke(Unit _arg1)
 (00:00:00.0017681)

2 tests run: 1 passed, 0 ignored, 1 failed, 0 errored (00:00:00.0058780)

If you run this within Visual Studio with F5 you can navigate to the failing assertion by clicking on the line that looks like a mini stack trace.

REPL it!

Since running tests is as easy as saying "run test", it's also convenient sometimes to do so from the F# REPL.

Pros:

  • You can directly load the source code under tests in the REPL, which cuts down compilation times.
  • Easy to cherry-pick one or a few tests to run instead of running all tests (with the provided Test.filter function)

Cons:

  • Having to manually load all dependencies to the tests. It may be possible to work around this using a variant of this script by Gustavo Guerra.
  • If you reference the assembly under test in the REPL, fsi.exe blocks the DLLs, so you have to reset the REPL session to recompile. But if you're testing F# code, you can work around this by loading source code instead of referencing the assembly.

You can see an example of running tests from the REPL here.

Other tools

Integrating with other tools is not simple. Most tools out there seem to assume that tests are organized in classes, and each test corresponds to a method or function. This also happens with MbUnit's StaticTestFactory: for example in ReSharper or TestDriven.Net you can't single out tests. Still, they can be made to run let-bound tests (which may be a test suite), so it should be possible to have some support within this limitation.

Also, no immediate support for any continuous test runner. I checked with Greg Young, he tells me that MightyMoose/AutoTest.NET can be configured to use an arbitrary executable (with limitations). Remco Mulder, of NCrunch, suggested wrapping the test runner in a test from a known test framework as a workaround. Maybe executing the tests after compilation (with a simple AfterBuild msbuild target) is enough. I haven't looked into this yet.

Coverage tools should have no problem, it makes no difference where the executable comes from.

Build tools should have no issues either; obviously FAKE is the more direct option, but I see no problems integrating this with other build tools.

C# support

I threw in a few wrapper functions to make this library usable in C# / VB.NET. Of course, it will never be as concise as F#, but still usable. I'm not going to fully explain this (it's just boring sugar) but you can see an example here.

NUnit/MbUnit test loading

Even though it may seem very different, Fuchu is still built on xUnit concepts. And since tests are first-class values, it's very easy to map tests written with other xUnit framework to Fuchu tests. For example, building Fuchu tests from NUnit test classes takes less than 100 LoC (it's already built into Fuchu)

This lets you use Fuchu as a runner for existing tests, and to write new tests. I'm planning to use this soon in SolrNet to replace Gallio (for example, Gallio doesn't work on Mono).

There is a limitation here: Fuchu can't express TestFixtureTearDowns. It can do TestFixtureSetups (and obviously SetUp/TearDown, as explained in previous posts), but not TestFixtureTearDowns (or at least not unless you treat that test suite separately). Give it a try and see for yourself :) . Is it a real downside? I don't think so (for example, TestFixtureTearDowns make parallelization harder), but it's something to be aware of. Also I haven't looked into test inheritance yet, but it should be pretty easy to support it.

Conclusions

Does .NET really need yet another test framework? Absolutely not. The current test frameworks are "good enough" and hugely popular. But since they don't treat tests as first-class values, extending them results in more and more complexity. Consider the lifecycle of a test in a typical unit testing framework. Inheritance and multiple marker attributes make it so complex that it reminds me of the ASP.NET page lifecycle

What I propose with Fuchu is a hopefully simpler, no-magic model. Remember KISS?

Code is here. Binaries on NuGet.

Friday, May 11, 2012

An F# DSL for MbUnit

In F# we typically organize tests much like in C# or VB.NET: writing functions marked with a [<Test>] attribute or similar. Actually there's a slight advantage in F#: you don't need to write a class marked as test fixture, you can directly write the tests as let-bound functions. Still, it's fundamentally the same model. (If you're into BDD there's also TickSpec as an alternative model).

Since it's the same model, you get the same issues I described in my last post, and then some: for example as Kurt explains, attributes in F# sometimes aren't treated exactly as in C#.

Also in my last post, I wrote about how MbUnit supports first-class tests as an alternative to attribute-defined tests. In F# we can take advantage of this and custom operators to build a very concise DSL to define tests.

First let's see a small test suite with setup/teardown, written with the classic attributes:

[<TestFixture>]
type ``MemoryStream tests``() =
    let mutable ms : MemoryStream = null

    [<SetUp>]
    member x.Setup() =
        ms <- new MemoryStream()

    [<TearDown>]
    member x.Teardown() =
        ms.Dispose()

    [<Test>]
    member x.``Can read``() =
        Assert.IsTrue ms.CanRead

    [<Test>]
    member x.``Can write``() =
        Assert.IsTrue ms.CanWrite

Looks simple enough, right? And yet, the mutable field is a smell, or at least an indicator that this isn't functional. Let's try to get rid of that mutable.

As a first step we'll rewrite this as first-class tests, that is, using [<StaticTestFactory>] as shown in my last post:

[<StaticTestFactory>]
let testFactory() =
    let suite = TestSuite("MemoryStream tests")
    let ms : MemoryStream ref = ref null
    suite.SetUp <- fun () -> ms := new MemoryStream()
    suite.TearDown <- fun () -> (!ms).Dispose()
    let tests = [
        TestCase("Can read", 
            fun () -> Assert.IsTrue (!ms).CanRead)
        TestCase("Can write", 
            fun () -> Assert.IsTrue (!ms).CanWrite)
    ]
    Seq.iter suite.Children.Add tests
    [suite]

Oh great, that's even uglier than what we started with! And we have replaced the mutable field with a ref cell, not much of an improvement. 
But bear with me, we have first-class tests now so there's a lot a room for improvement.

In order to keep refactoring this, we need to realize that the problem is that our test cases should be functions MemoryStream -> unit instead of unit -> unit. That way, they wouldn't have to depend on an external MemoryStream instance; instead the instance would be pushed somehow to the test. Let's write that:

let tests = [
    "Can read", (fun (ms: MemoryStream) -> Assert.IsTrue ms.CanRead)
    "Can write", (fun ms -> Assert.IsTrue ms.CanWrite)
]

Now we have this list of strings and MemoryStream -> unit functions. What we need now is to turn these functions into unit -> unit so we can ultimately build TestCases.

In other words, we need a function (MemoryStream -> unit) -> (unit -> unit). This function should create the MemoryStream, pass it to our test function, then dispose the MemoryStream. Hey, what do you know, turns out that's just what SetUp and TearDown do!

Still with me? It's much easier to see this in code:

let withMemoryStream f () = 
    use ms = new MemoryStream()
    f ms

Now we apply this to our list, building the TestCases and then the TestSuite:

[<StaticTestFactory>]
let testFactory() =
    let suite = TestSuite("MemoryStream tests")
    tests 
    |> Seq.map (fun (n,t) -> TestCase(n, Gallio.Common.Action(withMemoryStream t)))
    |> Seq.iter suite.Children.Add
    [suite]

We've eliminated all mutable references, and also replaced SetUp/TearDown with a simple higher-order function.

But we can do still better, in terms of readability. We can define a few custom operators to hide the TestSuite and TestCase constructors:

let inline (=>>) name tests =
    let suite = TestSuite(name)
    Seq.iter suite.Children.Add tests
    suite :> Test

let inline (=>) name (test: unit -> unit) =
    TestCase(name, Gallio.Common.Action test) :> Test

[<StaticTestFactory>]
let testFactory() =
    [
        "MemoryStream tests" =>> [
            "Can read" => 
                withMemoryStream(fun ms -> Assert.IsTrue ms.CanRead)
            "Can write" => 
                withMemoryStream(fun ms -> Assert.IsTrue ms.CanWrite)
        ]
    ]

And with a couple more operators we get rid of the duplicate call to withMemoryStream:

let inline (+>) f =
     Seq.map (fun (name, partialTest) ->
                    name => f partialTest)

let inline (==>) (name: string) test = name,test

[<StaticTestFactory>]
let testFactory() =
    [
        "MemoryStream tests" =>>
            withMemoryStream +> [
                "Can read" ==> 
                    fun ms -> Assert.IsTrue ms.CanRead
                "Can write" ==>
                    fun ms -> Assert.IsTrue ms.CanWrite
            ]
    ]

Conclusions

Confused about all those kinds of arrows? The good thing about first-class tests is that you can build them any way you want, no need to use these operators if you don't like them. That's also precisely one of its downsides: as there is no fixed idiom, it can get harder to read compared to attribute-based test definitions, where there is a single, well-defined way to do things.

In my last post I showed how first-class tests practically eliminate the concept of parameterized tests. In this post I showed how they eliminate the concept of setup/teardown, replacing them with a higher-order function, a more generic concept.

More generally, I'd say that whatever domain you're modeling (in this case, tests), there is much to gain if the core concepts are representable as first-class values. It should also be noted that different languages have very different notions of what language objects are first-class values. Some are more flexible than others, but that doesn't imply any superiority by itself. However it does mean that if you're not aware of this you'll probably misuse your language and end up with ever more complex workarounds to manipulate your domain objects as values. Nice APIs, conventions, configuration, etc, are all secondary and can be built much more easily on top of composable, first-class building blocks.

But I digress. In the next post I'll show a simple testing library built around tests as first-class values and more pros/cons about this approach.

Friday, March 2, 2012

Wrapping visitors with active patterns in F#

In the last post I showed how to interop F# and C# algebraic data types (ADT).

In C# you'll typically have ADTs or ADT-like structures expressed as a hierarchy of classes and the Visitor pattern to traverse/deconstruct them.

So the question is: what's the best way to use C#/VB.NET visitors in F#?

As an example, let's borrow a C# - F# comparison from Stackoverflow by Juliet Rosenthal, which models boolean operations:

public interface IExprVisitor<out T> {
    T Visit(TrueExpr expr);
    T Visit(And expr);
    T Visit(Nand expr);
    T Visit(Or expr);
    T Visit(Xor expr);
    T Visit(Not expr);
}

public abstract class Expr {
    public abstract t Accept<t>(IExprVisitor<t> visitor);
}

public abstract class UnaryOp : Expr {
    public Expr First { get; private set; }

    public UnaryOp(Expr first) {
        First = first;
    }
}

public abstract class BinExpr : Expr {
    public Expr First { get; private set; }
    public Expr Second { get; private set; }

    public BinExpr(Expr first, Expr second) {
        First = first;
        Second = second;
    }
}

public class TrueExpr : Expr {
    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

public class And : BinExpr {
    public And(Expr first, Expr second) : base(first, second) {}

    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

public class Nand : BinExpr {
    public Nand(Expr first, Expr second) : base(first, second) {}

    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

public class Or : BinExpr {
    public Or(Expr first, Expr second) : base(first, second) {}

    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

public class Xor : BinExpr {
    public Xor(Expr first, Expr second) : base(first, second) {}

    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

public class Not : UnaryOp {
    public Not(Expr first) : base(first) {}

    public override t Accept<t>(IExprVisitor<t> visitor) {
        return visitor.Visit(this);
    }
}

Let's say we want to write a function in F# to evaluate a boolean expression using these classes. We could use an object expression to create an inline visitor:

let rec eval (e: Expr) =
    e.Accept { new IExprVisitor<bool> with
                member x.Visit(e: TrueExpr) = true
                member x.Visit(e: And)      = eval(e.First) && eval(e.Second)
                member x.Visit(e: Nand)     = not(eval(e.First) && eval(e.Second))
                member x.Visit(e: Or)       = eval(e.First) || eval(e.Second)
                member x.Visit(e: Xor)      = eval(e.First) <> eval(e.Second)
                member x.Visit(e: Not)      = not(eval(e.First)) }

This is already more concise than the equivalent C# code, but we can do better. Once again, active patterns are the key. We only need one visitor to do the required plumbing:

module Expr = 
    open DiscUnionInteropCS

    type ExprChoice = Choice<unit, Expr * Expr, Expr * Expr, Expr * Expr, Expr * Expr, Expr>

    let private visitor = 
        { new IExprVisitor<ExprChoice> with
            member x.Visit(e: TrueExpr): ExprChoice = Choice1Of6 ()
            member x.Visit(e: And):      ExprChoice = Choice2Of6 (e.First, e.Second)
            member x.Visit(e: Nand):     ExprChoice = Choice3Of6 (e.First, e.Second)
            member x.Visit(e: Or):       ExprChoice = Choice4Of6 (e.First, e.Second)
            member x.Visit(e: Xor):      ExprChoice = Choice5Of6 (e.First, e.Second)
            member x.Visit(e: Not):      ExprChoice = Choice6Of6 e.First }

    let (|True|And|Nand|Or|Xor|Not|) (e: Expr) =
        e.Accept visitor

And now we can write eval more idiomatically and more concise:

let rec eval = 
    function
    | True          -> true
    | And(e1, e2)   -> eval(e1) && eval(e2)
    | Nand(e1, e2)  -> not(eval(e1) && eval(e2))
    | Or(e1, e2)    -> eval(e1) || eval(e2)
    | Xor(e1, e2)   -> eval(e1) <> eval(e2)
    | Not(e1)       -> not(eval(e1))

This also opens the doors for more complex pattern matching. See Juliet's post for an example.

Thursday, March 1, 2012

Algebraic data type interop: F# - C#

In a previous post I wrote about encoding algebraic data types in C#. Now let's explore the interoperability issues that arise when defining and consuming algebraic data types (ADTs) cross-language in C# and F#. More concretely, let's analyze construction and deconstruction of an ADT and how to keep operations as idiomatic as possible while also retaining type safety.

Defining an ADT in F# and consuming it in C#

In F#, ADTs are called discriminated unions. The first thing I should mention is that the F# component design guidelines recommend hiding discriminated unions as part of a general .NET API. I prefer to interpret it like this: if you can hide it with minor consequences, or you have stringent binary backwards compatibility requirements, or you foresee it changing a lot, hide it. Otherwise I wouldn't worry much.

Let's use this simple discriminated union as example:

type Shape =
| Circle of float
| Rectangle of float * float

Construction in C# is pretty straightforward: F# exposes static methods NewCircle and NewRectangle:

var circle = Shape.NewCircle(23.77);
var rectangle = Shape.NewRectangle(1.5, 2.2);

No, you can't use constructors directly to instantiate Circle or Rectangle, F# compiles these constructors as internal. No big deal really.

Deconstruction, however, is a problem here. C# doesn't have pattern matching, but as I showed in the previous article you can simulate this with a Match() method like this:

static class ShapeExtensions {
    public static T Match<T>(this Shape shape, Func<double, T> circle, Func<double, double, T> rectangle) {
        if (shape is Shape.Circle) {
            var x = (Shape.Circle)shape;
            return circle(x.Item);
        }
        var y = (Shape.Rectangle)shape;
        return rectangle(y.Item1, y.Item2);
    }
}

Here we did it as an extension method in the consumer side of things (C#). The problem with this is, if we add another case to Shape (say, Triangle), this will still compile successfully without even a warning, but fail at runtime, instead of failing at compile-time as it should!

It's best to define this in F# where we can take advantage of exhaustively-checked pattern matching, either as a regular instance member of Shape or as an extension member:

[<Extension>]
type Shape with
    [<Extension>]
    static member Match(shape, circle: Func<_,_>, rectangle: Func<_,_,_>) =
        match shape with
        | Circle x -> circle.Invoke x
        | Rectangle (x,y) -> rectangle.Invoke(x,y)

This is how we do it in FSharpx to work with Option and Choice in C#.

Defining an ADT in C# and consuming it in F#

Defining an ADT in C# is already explained in my previous post. But how does this encoding behave when used in F#?

To recap, the C# code we used is:

namespace DiscUnionInteropCS {
    public abstract class Shape {
        private Shape() {}

        public sealed class Circle : Shape {
            public readonly double Radius;

            public Circle(double radius) {
                Radius = radius;
            }
        }

        public sealed class Rectangle : Shape {
            public readonly double Height;
            public readonly double Width;

            public Rectangle(double height, double width) {
                Height = height;
                Width = width;
            }
        }

        public T Match<T>(Func<double, T> circle, Func<double, double, T> rectangle) {
            if (this is Circle) {
                var x = (Circle) this;
                return circle(x.Radius);
            }
            var y = (Rectangle) this;
            return rectangle(y.Height, y.Width);
        }
    }
}

Just as before, let's analyze construction first. We could use constructors:

let shape = Shape.Circle 2.0

which looks like a regular F# discriminated union construction with required qualified access. There are however two problems with this:

  1. Object constructors in F# are not first-class functions. Try to use function composition (>>) or piping (|>) with an object constructor. It doesn't compile. On the other hand, discriminated union constructors in F# are first-class functions.
  2. Concrete case types lead to unnecessary upcasts. shape here is of type Circle, not Shape. This isn't much of a problem in C# because it upcasts automatically, but F# doesn't, and so a function that returns Shape would require an upcast.

Because of this, it's best to wrap constructors:

let inline Circle x = Shape.Circle x :> Shape
let inline Rectangle (a,b) = Shape.Rectangle(a,b) :> Shape

Let's see deconstruction now. In F# this obviously means pattern matching. We want to be able to write this:

let area =
    match shape with
    | Circle radius -> System.Math.PI * radius * radius
    | Rectangle (h, w) -> h * w

We can achieve this with a simple active pattern that wraps the Match method:

let inline (|Circle|Rectangle|) (s: Shape) =
    s.Match(circle = (fun x -> Choice1Of2 x),
            rectangle = (fun x y -> Choice2Of2 (x,y)))

For convenience, put this all in a module:

module Shape =
    open DiscUnionInteropCS

    let inline Circle x = Shape.Circle x :> Shape
    let inline Rectangle (a,b) = Shape.Rectangle(a,b) :> Shape
    let inline (|Circle|Rectangle|) (s: Shape) =
        s.Match(circle = (fun x -> Choice1Of2 x),
                rectangle = (fun x y -> Choice2Of2 (x,y)))

So with a little boilerplate you can have ADTs defined in C# behaving just like in F# (modulo pretty-printing, comparison, etc, but that's up the C# implementation if needed). No need to to define a separate, isomorphic ADT.

Note that pattern matching on the concrete type of a Shape would easily break, just like when we defined the ADT in F# with Match in C#. By using the original Match, if the original definition is modified, Match() will change and so the active pattern will break accordingly at compile-time. If you need binary backwards compatibility however, it's going to be more complex than this.

In the next post I'll show an example of a common variant of this.

By the way it would be interesting to see how ADTs in Boo and Nemerle interop with F# and C#.

Monday, November 28, 2011

A few FSharpx examples

FSharpx doesn't currently have any proper documentation, and even comments are lacking despite what ohloh says. We will definitely improve the comments, but a reference documentation isn't going to help at all if you don't know the underlying concepts and how things fit together. A good way to introduce these concepts is by using examples that deal with familiar problems. Stackoverflow has proven to be a great source of real-world use cases for many FSharpx features, which also serve to grow it with new features. Here are the F# questions I answered last week using FSharpx I'd like to elaborate. I recommend following the links to the original questions and reading the other answers for comparison.

List multiplication

The question is about doing a cartesian product. Of course, in F# this is pretty trivial to achieve thanks to list comprehensions, but FSharpx has a couple of functions to help express this more directly:

First there's List.lift2. Its signature is ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list .

If you're familiar with F# you'll notice this is similar to the standard function List.map2, which has the exact same signature. So what's the difference?

List.map2 works pairwise. Its result has the exact same number of elements as the parameters. Let's see an example:

> List.map2 (+) [0;1] [0;2];;

[0;3]

That is, it adds 1st element in the first list to 1st element in the second list, and 2nd to 2nd.

List.lift2 does precisely a cartesian product. Let's try it with the same parameters as above:

> List.lift2 (+) [0;1] [0;2];;

[0;2;1;3]

It adds 1st to 1st, 1st to 2nd, 2nd to 1st, 2nd to 2nd.

Same signature, very different semantics.

The name lift2 comes from lifting a function (a binary function, in this case, hence '2') to a monad (the F# list as a monad in this case). In Haskell this function is generalized to all monads and called liftM2. In F# it's also the same as liftA2, which lifts a function to an applicative functor, because there isn't really a first-class concept of monads or applicatives in F#. As an exercise, try writing the monadic 'bind' and 'return' for an F# list, then lift2 in terms of them. You can also implement lift2 using applicative functors, try it. Both exercises are quite enlightening once they 'click'.

But the question asked for a result in tuples. So we could say:

List.lift2 (fun a b -> a,b) [1..30] [1..30]

Tupling elements is a pretty common operation, so FSharpx offers a function tuple2 that does just that (and tuple3 up to tuple6. If you need more than that you probably shouldn't be using a tuple). To summarize:

List.lift2 tuple2 [1..30] [1..30]

With list comprehensions:

[ for x in [1..30] do
    for y in [1..30] do
        yield x,y ]

I think pointfree style wins here if you're familiar with monads.

Updating nested immutable data structures

In which the developer has a few nested immutable records and wants to write a mapping function that reaches deep inside this nesting. The record types model a role-playing game:

type Monster = { 
    Awake: bool 
}

type Room = { 
    Locked: bool 
    Monsters: Monster list 
}

type Level = { 
    Illumination: int 
    Rooms: Room list 
}

type Dungeon = { 
    Levels: Level list 
}

How to write a mapping function that transforms all Monsters in all Rooms within a particular Level of a Dungeon?

In other words, a function mapMonstersOnLevel : int -> (Monster -> Monster) -> Dungeon -> Dungeon .

Let's roll up our sleeves!

let mapMonstersOnLevel nLevel f dungeon =
  let levelMap (level: Level) =
    { level with Rooms = 
                 List.map (fun room -> 
                            { room with Monsters = List.map f room.Monsters }) level.Rooms }
  { dungeon with Levels = 
                 List.mapi (fun i level -> 
                             if i = nLevel then levelMap level else level) dungeon.Levels }

Using lenses we can express this much more concisely and elegantly. After the dreaded but necessary boilerplate for lenses (each field in each record must have an associated lens explicitly spelled out), we are left with:

let mapMonstersOnLevel nLevel f =
    Dungeon.levels >>| Lens.forList nLevel >>| Level.rooms >>| Lens.listMap Room.monsters
    |> Lens.update (f |> List.map |> List.map)

Lenses are quite intuitive, I think it's pretty easy to grasp what's hapenning there, even if you've never seen lenses before. The only difference is that because a lens Update is a Get, followed by the transforming function, followed by a Set, this isn't as effective as the first version. It can be optimized, but I'm not sure it's worth it, updating an element in an immutable list is still O(n), it doesn't matter much if it needs an extra pass.

Exception handling in pipeline sequence

An initial state is pipelined along a series of functions that modify this state. The state in question is a point on a plane, but that's not important. Problem is, each function can throw, and when that happens the whole computation must be aborted and an error must be shown.

Initially, the problem is posed like this:

let startingPosition = 0. ,0.

let moveByLengthAndAngle l a (x,y) = x,y // too lazy to do the math
let moveByXandY dx dy (x,y) = x+dx, y+dy
let moveByXandAngle dx a (x,y) = x+dx, y

let finalPosition =
    startingPosition
    |> moveByLengthAndAngle x1 a1 
    |> moveByXandY x2 y2
    |> moveByXandAngle x3 a3
    |> moveByLengthAndAngle x4 a4
    // etc...

Instead of doing this, let's represent the computation as a list of partially applied functions with the associated error messages:

let actions = 
    [
        moveByLengthAndAngle x1 a1, "failed first moveByLengthAndAngle"
        moveByXandY x2 y2, "failed moveByXandY"
        moveByXandY x3 y3, "failed moveByXandY"
        moveByXandAngle x3 a3, "failed moveByXandAngle"
        moveByLengthAndAngle x4 a4, "failed second moveByLengthAndAngle"
    ]

And then fold over this list of actions, starting with the initial point and accumulating the result of each function. In the folding function we must also catch any potential exception and put the error message instead, and abort the rest of the computation. But the state is a pair of floats and the error message obviously a string, so we model the actual state as a Choice of either the pair of floats or a string (i.e. Choice<float * float, string> ):

let finalPosition = 
    let evalToChoice (f,message) a =
        try
            f a |> Choice1Of2
        with _ -> Choice2Of2 message
    let folder a f = 
        match a with 
        | Choice2Of2 a -> Choice2Of2 a 
        | Choice1Of2 a -> f a
    actions 
    |> List.map evalToChoice
    |> List.fold folder (Choice1Of2 startingPosition)

All that's left to do is pattern match on finalPosition to see if the computation ended up as error or completed successfully:

match finalPosition with
| Choice1Of2 (x,y) -> 
    printfn "final position: %f,%f" x y
| Choice2Of2 error -> 
    printfn "error: %s" error

FSharpx has a couple of abstractions (mostly borrowed from Haskell, as usual) that help reduce the clutter here:

Firstly, FSharpx defines a monad around Choice1Of2 / Choice2Of2. This is like the Either monad defined in Haskell or Scalaz, except we call it Choice because... well, the F# type is already called Choice. So we have Choice.bind and returnM (actually 'return' is just the constructor Choice1Of2). The convention here is that Choice1Of2 carries the successful branch of the computation and Choice2Of2 carries the error.

FSharpx also defines bifunctor for Choice. In Scalaz and Haskell this is a typeclass (of which Either is an instance), but in FSharpx this is simply two functions bimap and mapSecond. Bimap takes two mapping functions, and uses the first one to map the Choice1Of2 part of a Choice, and the other one to map the Choice2Of2 part. mapSecond only maps the Choice2Of2 part of a choice. What about mapFirst? It's simply map.

Since Choice/Either is frequently used in pure functional programming to represent errors, and we're working in an impure language, it makes sense to have a library function to convert a function that throws as a means to report an error into a function that returns a Choice, where the Choice2Of2 part is the potential exception. This seems to be pretty common in Scala, and it's what Choice.protect in FSharpx does. The signature is pretty explicit: ('a -> 'b) -> 'a -> Choice<'b,exn>

Putting all the pieces together:

let finalPosition = 
    let folder position (f,message) =
        Choice.bind (Choice.protect f >> Choice.mapSecond (konst message)) position
    List.fold folder (Choice1Of2 startingPosition) actions

Haskellers have long ago recognized this folding with a monadic result and abstracted it into a generic function foldM. As usual, in F# we can't express this generically for any monad, but we can write it for every monad. With foldM the code looks like this:

let finalPosition = 
    let folder position (f,message) = 
        Choice.protect f position |> Choice.mapSecond (konst message)
    Choice.foldM folder startingPosition actions

A different approach to the problem is to rethrow the message as an exception, instead of using Choices. This is quite concise as well:

let finalPosition() = 
    let evalRethrow (f,message) a =
        try f a with _ -> failwith message
    actions
    |> List.map evalRethrow
    |> List.fold (|>) startingPosition

Instead of pattern matching over the result, you'd invoke this function in a try..with block:

try
    let x,y = finalPosition()
    printfn "final position: %f,%f" x y
with e -> 
    printfn "error: %s" e.Message

The problem with using exceptions is that they're not really part of the type system. The function finalPosition is of type unit -> float*float . This doesn't say it might throw an exception, so you can't statically enforce handling the error case. Also, exceptions are actually misused here: having an error in the computation is an expected result, not a programming error. I recommend reading Errors vs Exceptions for more information on this. The terms 'exception' and 'error' may sometimes be used in one way or the other, but it's always useful to make the distinction.

Also worth noting is how representing the computations as a list of actions with associated data (in this case, the messages) allows us to freely choose how to evaluate it.

Using F# datatypes in C#

FSharpx is not just for F# consumers. I blogged before about using the F# runtime as a library in C# apps. FSharpx adds some sugar so you can use F# persistent collections in C# quite comfortably. Here's an example:

var a = FSharpList.Create(1, 2, 3);
var b = a.Cons(0);
b.TryFind(x => x > 4)
 .Match(v => Console.WriteLine("I found a value {0}", v),
        () => Console.WriteLine("I didn't find anything"));