Me, A Name I Call Myself

In F#, unlike other CLR languages, you can define the self-identifier┬áthat a class uses, rather than being restricted to a language-specific one. If you come from a C# background (as I do), you might be tempted to use “this”, as it is familiar.

namespace ItWorksOnMyMachine

type MyFirstFSharpClass(m: int) =
    let l = seq {for i in 1..100 do yield i}
            |> Seq.toList

    let n = 2 * m     

    member this.Multiples () =          
        let isMultiple =             
            fun i -> i % n = 0

        l |> Seq.filter isMultiple

This is perfectly reasonable, but the above code demonstrates a possibly confusing situation when debugging this code. If a breakpoint is placed at line 13, we can inspect the value of n using this.n:

watch1

However, if the breakpoint is placed at line 11 then things get confusing:

watch2

The type of “this” has changed, because it now refers to the compiler-generated class used to hold the let binding! In order to access the same instance we now need to use “this.this.n”:

watch3

If I wanted “this” to point to different things at different times, I’d write code in JavaScript. However, being of reasonably sane disposition, I prefer a little more consistency. My attempted solution was to use “me” as the F# self-identifier, but this just introduces a fresh hell:

watch4

How can “me” not exist when the breakpoint is in the method body?

watch5

Oh, but it does exist when the breakpoint is in the compiler-generated class! Time for me to go and lie down…

Leave a Reply