F# 21 : Events

We continue our OO journey, and this time we look at events within classes.

Events are a good way for no related classes t communicate, you can think of events as a kind of publish-subscribe arrangement, where the source of the event (the class that contains the event) is the publisher, whilst a consumer of the event is the subscriber.

According to MSDN (http://msdn.microsoft.com/en-us/library/dd233189.aspx)

F# events are represented by the F# Event class, which implements the IEvent interface. IEvent is itself an interface that combines the functionality of two other interfaces, IObservable<T> and IDelegateEvent. Therefore, Events have the equivalent functionality of delegates in other languages, plus the additional functionality from IObservable, which means that F# events support event filtering and using F# first-class functions and lambda expressions as event handlers.

This is actually pretty cool, as we can use the full gamut of Observable functions with F# events straight out of the box

 

 

 

 

 

 

Adding Events To A Class

Here is some code that shows how to add custom events to a custom class. There are several key points here:

  • We need to declare a private let binding which may or may not be a generic new Event type  (depending on how you want your event to work more on this later)
  • We need to use a CLIEvent attribute on the member itself. This instructs the compiler to emit a CLR type event signature with the standard Add/Remove event handler methods
  • We need to use the .Publish from the private event value when exposing the member
  • We can raise the event using the Trigger(..) function of the private event. The Trigger function call will need to match the type of the Event arguments you chose to use, if you chose to let it be anything using the “Event<_>”, then it should take the form of this, args, which is the sender(ie this class), and the event args you want to use
type MyCustomEventArgs<'a>(value : string) =
    inherit System.EventArgs()

    member this.Value = value

type MyCustomDelegate<'a> = delegate of obj * MyCustomEventArgs<'a> -> unit

type MyClassWithCLIEvent<'a when 'a : comparison>() =

    let customEventArgsEvent = new Event<string>()
    let genericEventArgsEvent = new Event<_>()
    let standardDotNetEventArgsEvent = new Event<EventHandler, EventArgs>()
    let customEventHandlerEvent = new Event<MyCustomDelegate<string>, MyCustomEventArgs<string>>()

    [<CLIEvent>]
    member this.CustomEventArgsEvent = customEventArgsEvent.Publish

    [<CLIEvent>]
    member this.GenericEventArgsEvent = genericEventArgsEvent.Publish

    [<CLIEvent>]
    member this.StandardDotNetEventArgsEvent = standardDotNetEventArgsEvent.Publish

    [<CLIEvent>]
    member this.CustomEventHandlerEvent = customEventHandlerEvent.Publish

    member this.TestCustomEventArgsEvent(arg : string) =
        customEventArgsEvent.Trigger(arg)

    member this.TestGenericEventArgsEvent(args : string) =
        genericEventArgsEvent.Trigger(this, args)

    member this.TestStandardDotNetEventArgsEvent() =
        standardDotNetEventArgsEvent.Trigger(this, EventArgs.Empty)

    member this.TestCustomEventHandlerEvent(x) =
        customEventHandlerEvent.Trigger(this, new MyCustomEventArgs<_>(x))

 

Raising Events

We just saw this above where we use the Trigger(..) function of the Event that is being exposed. This would tyically be done is a function that could be  used internally, though you may want to expose the facility to raise the event outside the class that has the event, but in my opinion that would should be quite a rare case.

 

Subscribing To Events

Suppose we had this VERY simple win forms F# application with this code. This code actually shows you how to subscribe to 2 exists events, namely

  • Form.MouseMove : Which expects to have a event handler which takes System.Windows.Forms.MouseEventArgs, so in the handler we setup we make sure that the event arguments are just that.
  • Form.Click : Which expects to have System.EventArgs

 

When subscribing to events you have 2 choices:

  1. You may use the Add which has the following signature callback: (’T –> unit) –> unit
  2. You may also use the AddHandler

It is really just a question of creating your correct event handlers and then Adding them to the events invocation list using the Add(..) function

 

open System.Windows.Forms

[<EntryPoint>]
let main argv = 

    let ShowMessageOnClickHandler evArgs =
        MessageBox.Show("Clicked") |> ignore

    let form = new Form(Text = "F# Windows Form",
                        Visible = true,
                        TopMost = true)

    let MouseMoveEventHandler (evArgs : System.Windows.Forms.MouseEventArgs) =
        form.Text <- System.String.Format("{0},{1}", evArgs.X, evArgs.Y)

    //adds the Click handler delegate (function in F#)
    form.Click.Add(ShowMessageOnClickHandler)

    //adds the MouseMove handler delegate (function in F#)
    form.MouseMove.Add(MouseMoveEventHandler)
    Application.Run(form)

    0

 

If you run this code, and click anywhere on the form you will get a MessageBox shown

image

 

Lets revisit our custom class that had it own events where we had this code:

 

type MyCustomEventArgs<'a>(value : string) =
    inherit System.EventArgs()

    member this.Value = value

type MyCustomDelegate<'a> = delegate of obj * MyCustomEventArgs<'a> -> unit

type MyClassWithCLIEvent<'a when 'a : comparison>() =

    let customEventArgsEvent = new Event<string>()
    let genericEventArgsEvent = new Event<_>()
    let standardDotNetEventArgsEvent = new Event<EventHandler, EventArgs>()
    let customEventHandlerEvent = new Event<MyCustomDelegate<string>, MyCustomEventArgs<string>>()

    [<CLIEvent>]
    member this.CustomEventArgsEvent = customEventArgsEvent.Publish

    [<CLIEvent>]
    member this.GenericEventArgsEvent = genericEventArgsEvent.Publish

    [<CLIEvent>]
    member this.StandardDotNetEventArgsEvent = standardDotNetEventArgsEvent.Publish

    [<CLIEvent>]
    member this.CustomEventHandlerEvent = customEventHandlerEvent.Publish

    member this.TestCustomEventArgsEvent(arg : string) =
        customEventArgsEvent.Trigger(arg)

    member this.TestGenericEventArgsEvent(args : string) =
        genericEventArgsEvent.Trigger(this, args)

    member this.TestStandardDotNetEventArgsEvent() =
        standardDotNetEventArgsEvent.Trigger(this, EventArgs.Empty)

    member this.TestCustomEventHandlerEvent(x) =
        customEventHandlerEvent.Trigger(this, new MyCustomEventArgs<_>(x))

When you declare your Event<’T>, one of the things you need to decide is what type of event handler you want to expose/allow users to use, this will dictate what type of Event<’T> you will declare. The above code demonstrates 3 possible flavours of Event<’T>, which are:

  1. Custom event argument type
  2. Generic event arguments
  3. Standard Handler/EventArgs which will be of the type sender EventArgs (this is the standard in .NET), you could obviously use any EventHandler and EventArgs you like
  4. Custom EventHandler delegate and EventArgs

 

 

 

Custom EventArgs

As can be seen from the code that when we choose to use a custom object type for the event we end up with this sort of code in the event source class

type MyClassWithCLIEvent<'a when 'a : comparison>() =

    let customEventArgsEvent = new Event<string>()

    [<CLIEvent>]
    member this.CustomEventArgsEvent = customEventArgsEvent.Publish

    member this.TestCustomEventArgsEvent(arg : string) =
        customEventArgsEvent.Trigger(arg)

Where we can subscribe using this sort of code when subscribing

    let classWithEvent = new MyClassWithCLIEvent<string>()

    let handler = new Handler<string>(fun sender args -> printfn "CustomEventArgsEvent AddHandler with new Handler<string> : %s" args)
    classWithEvent.CustomEventArgsEvent.AddHandler(handler)

    classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")
    classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")
    classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")

    //removing handler for CustomEventArgsEvent, so it should not fire any more
    classWithEvent.CustomEventArgsEvent.RemoveHandler(handler)
    classWithEvent.TestCustomEventArgsEvent("I Am event1")
    classWithEvent.TestCustomEventArgsEvent("I Am event1")
    classWithEvent.TestCustomEventArgsEvent("I Am event1")

 

 

 

 

 

Generic Event Arguments

As can be seen from the code that when we choose to use a generic Event<..> we end up with this sort of code in the event source class

type MyClassWithCLIEvent<'a when 'a : comparison>() =

    let genericEventArgsEvent = new Event<_>()

    [<CLIEvent>]
    member this.GenericEventArgsEvent = genericEventArgsEvent.Publish

    member this.TestGenericEventArgsEvent(args : string) =
        genericEventArgsEvent.Trigger(this, args)

As can be seen from the code that when we choose to use a generic Event<..> type for the event we end up with this sort of code in the event source class, where we must use sender args when we subscribe. We need to match the args with the correct type when we raise the event as the raising method expects a string value in this example

    let classWithEvent = new MyClassWithCLIEvent<string>()

    classWithEvent.GenericEventArgsEvent.Add(fun (sender, arg) ->
            printfn "Event1 occurred! Object data: %s" arg)

    classWithEvent.TestGenericEventArgsEvent("I Am TestGenericEventArgsEvent")

 

 

 

 

Using Standard EventHandler/EventArgs

As can be seen from the code that when we choose to use a generic Event<EventHandler/EventArgs> we end up with this sort of code in the event source class

type MyClassWithCLIEvent<'a when 'a : comparison>() = 

    let standardDotNetEventArgsEvent = new Event<EventHandler, EventArgs>() 

    [<CLIEvent>]
    member this.StandardDotNetEventArgsEvent = standardDotNetEventArgsEvent.Publish

    member this.TestStandardDotNetEventArgsEvent() =
        standardDotNetEventArgsEvent.Trigger(this, EventArgs.Empty)

 

As can be seen from the code that when we choose to use a generic Event<EventHandler/EventArgs> type for the event we need to create a new EventHandler when we subscribe

    let classWithEvent = new MyClassWithCLIEvent<string>()

    classWithEvent.StandardDotNetEventArgsEvent.AddHandler(
        EventHandler(fun _ _ -> printfn "StandardDotNetEventArgsEvent.AddHandler"))

    classWithEvent.TestStandardDotNetEventArgsEvent()
    classWithEvent.TestStandardDotNetEventArgsEvent()

 

Using Custom Delegate And Custom EventArgs

We can also create our own custom EventHandler delegate and create completely custom EventArgs, this is shown below:

type MyClassWithCLIEvent<'a when 'a : comparison>() =

    let customEventHandlerEvent = new Event<MyCustomDelegate<string>, MyCustomEventArgs<string>>()

    [<CLIEvent>]
    member this.CustomEventHandlerEvent = customEventHandlerEvent.Publish

    member this.TestCustomEventHandlerEvent(x) =
        customEventHandlerEvent.Trigger(this, new MyCustomEventArgs<_>(x))

As can be seen from the code that when we choose to use a custom EventHandler delegate, we need to use an instance of the custom EventHandler delegate when we subscribe

    let classWithEvent = new MyClassWithCLIEvent<string>()

    let delegateHandler = new MyCustomDelegate<string>(fun sender args -> printfn "CustomEventArgsEvent AddHandler new MyCustomDelegate<string> : %s" args.Value)
    classWithEvent.CustomEventHandlerEvent.AddHandler(delegateHandler)

    classWithEvent.TestCustomEventHandlerEvent("I Am TestCustomEventHandlerEvent")

 

 

 

If you use events you will undoubtedly know about the problem where the subscriber may outlive the source of an event, and if we do not unhook an event handler we will get a memory leak, so it will come as no surprise that we are also able to Remove events subscriptions using RemoveHandler.

Here is the full demo code:

let classWithEvent = new MyClassWithCLIEvent<string>()

let handler = new Handler<string>(fun sender args -> printfn "CustomEventArgsEvent AddHandler with new Handler<string> : %s" args)
classWithEvent.CustomEventArgsEvent.AddHandler(handler)

classWithEvent.GenericEventArgsEvent.Add(fun (sender, arg) ->
        printfn "Event1 occurred! Object data: %s" arg)

classWithEvent.StandardDotNetEventArgsEvent.AddHandler(
    EventHandler(fun _ _ -> printfn "StandardDotNetEventArgsEvent.AddHandler"))

let delegateHandler = new MyCustomDelegate<string>(fun sender args -> printfn "CustomEventArgsEvent AddHandler new MyCustomDelegate<string> : %s" args.Value)
classWithEvent.CustomEventHandlerEvent.AddHandler(delegateHandler)

classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")
classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")
classWithEvent.TestCustomEventArgsEvent("I Am TestCustomEventArgsEvent")
classWithEvent.TestGenericEventArgsEvent("I Am TestGenericEventArgsEvent")
classWithEvent.TestStandardDotNetEventArgsEvent()
classWithEvent.TestStandardDotNetEventArgsEvent()
classWithEvent.TestCustomEventHandlerEvent("I Am TestCustomEventHandlerEvent")

//removing handler for CustomEventArgsEvent, so it should not fire any more
classWithEvent.CustomEventArgsEvent.RemoveHandler(handler)
classWithEvent.TestCustomEventArgsEvent("I Am event1")
classWithEvent.TestCustomEventArgsEvent("I Am event1")
classWithEvent.TestCustomEventArgsEvent("I Am event1")

 

Which shows adding event subscriptions, and removing them too.

This produces the following output:

image

 

 

Implementing Interfaces That Contain Events

Occasionally you will get an interface or abstract class that has an event on it, and you need to implement the event in your type. A canonical example is the System.ComponentModel.INotifyPropertyChanged interface, which has the following attributes:

  1. Single PropertyChanged event
  2. PropertyChangedEventHandler delegate
  3. PropertyChangedEventArgs

 

So to implement this in your own code, you would simply do something like this:

open System
open System.Collections.Generic
open System.ComponentModel

type INPCObject() =
    let mutable total = 0.0
    let mutable name = ""

    let propertyChanged = Event<_, _>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish

    member this.Total
        with get() = total
        and  set(v) =
            total <- v
            propertyChanged.Trigger(this, new PropertyChangedEventArgs("Total"))

    member this.Name
        with get() = name
        and  set(v) =
            name <- v
            propertyChanged.Trigger(this, new PropertyChangedEventArgs("Name"))

Where you would hook up a subscription to this event, like this:

open System.ComponentModel
.....
.....
let classWithEvent = new INPCObject()

let inpc = (classWithEvent :> INotifyPropertyChanged)
inpc.PropertyChanged.AddHandler(
    (fun sender args -> printfn "PropertyChanged was : %s " args.PropertyName))

classWithEvent.Total <- 23.6;
classWithEvent.Name <- "yo";
classWithEvent.Total <- 11.2;

Which when run will give the following results:

image

 

MailBoxProcessor

Although not directly related to the subject at hand, I just want to mention a rather cool F# class called “MailBoxProcessor”, which is a message processing agent. It is quite cool, and could be used to send messages between objects with a little bit of love (think Mediator pattern here hint hint)

Here is a link to the class, have a read : http://msdn.microsoft.com/en-us/library/ee370357.aspx

 

Weak Events / Observable Module

Although slightly off topic for this brief introduction into F#, I thought it may be useful to point out some further resources that may help when working with events in general as well as Rx:

 

Further Reading I

Lovely Weak Event Article

This is a very in depth article about weak events, and presents several solutions to the problem, though the demos are in C#, it is still an excellent read, and one that everyone should read

 

Further Reading II

Paul Stovells Weak Event Proxy

A simple easy to use proxy to allow event subscription to be made weakly, which allows event source to be garbage collected even if a subscriber outlives the source life time.

I actually found a bit of time today to have a stab at translating Pauls Weak Event proxy into F#, which is shown below. Now this is not a generic version which Pauls original post was, but it was done with the purpose of demonstrating how to handle weak events, so if any of you want a generic version that is capable of dealing with any EventHandler delegate and EventArgs derived class it should not be that hard to change.

So here is the code, the crucial bit t note is that we hook the original source event up to a weak event (thanks to WeakReference) proxy, which will only raise the event if the event source is still alive. More crucially because we use a WeakReference we allow the original source object to be garbage collected, which is demonstrated when we set it to a default value and attempt to change one of its properties before we assign a new event source object.

Anyway enough waffle here is the code for the relevant types:

open System
open System.Diagnostics
open System.ComponentModel

//WeakPropertyChangedEventHandler for PropertyChangedEventHandler
[<DebuggerNonUserCode>]
type public WeakPropertyChangedEventHandler(callback : PropertyChangedEventHandler) =
    let _method = callback.Method
    let _targetReference  = new WeakReference(callback.Target, true);

    [<DebuggerNonUserCode>]
    member public this.Handler(sender, e : PropertyChangedEventArgs) =
        let target = _targetReference.Target;
        if (target <> null) then
            let callback = Delegate.CreateDelegate(typedefof<PropertyChangedEventHandler>, target, _method, true) @#58;@#63;> PropertyChangedEventHandler
            if (callback <> null) then
                callback.Invoke(sender, e);
            ()
        else
            ()

//Event Consumer
type SomeClassWithStoredEventObject(inpcObject) as this =
    let mutable eventSourceObject = inpcObject
    do this.HookEvent()

    member this.HookEvent() =
        let inpc = eventSourceObject :> INotifyPropertyChanged
        let inpcHandler = new PropertyChangedEventHandler(
            fun obj args -> printfn "Property Changed!")
        let WeakPropertyChangedEventHandler = new WeakPropertyChangedEventHandler(inpcHandler)
        let weakInpcHandler = new PropertyChangedEventHandler(
            fun obj args -> WeakPropertyChangedEventHandler.Handler(obj, args))
        do inpc.PropertyChanged.AddHandler(weakInpcHandler) |> ignore

    member this.EventSourceObject
        with get() = eventSourceObject
        and set(v) =
            eventSourceObject <- v
            this.HookEvent()

//Event producer
type INPCObject() =
    let mutable age = 0.0

    let propertyChanged = Event<_,_>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish

    member this.Age
        with get() = age
        and set(v) =
            age <- v
            propertyChanged.Trigger(this, new PropertyChangedEventArgs("Age"))

 

Where we have this consuming code:

let myObject = new INPCObject()
let someClassWithStoredEventObject = new SomeClassWithStoredEventObject(myObject)
myObject.Age <- 12.0
myObject.Age <- 24.0
let myObject = Unchecked.defaultof<INPCObject>
GC.Collect();
GC.WaitForPendingFinalizers();

let testItsNull x =
    if myObject = Unchecked.defaultof<INPCObject> then
        printfn "Yes it null now, so setting value should be an issue"
    try
        myObject.Age <- 35.0
    with
    | :? System.NullReferenceException as ex -> printfn "NullReferenceException! %s " (ex.Message); 

testItsNull myObject

let myObject2 = new INPCObject()
printfn "Assigning new Event Source object"
someClassWithStoredEventObject.EventSourceObject <- myObject2
myObject2.Age <- 35.0
myObject2.Age <- 89.0

Which when run gives the following output, which as you can see allows the original event source to be garbage collected:

image

 

Further Reading III

http://weblogs.asp.net/podwysocki/archive/2009/08/21/f-first-class-events-creating-and-disposing-handlers.aspx

F# blog posts which borrows ideas from Rx, to allow event subscriptions to return an IDisposable, such that they can be disposed using the standard .Dispose() method

 

Further Reading IV

Observable module in F#,

Some of Rx in F#, we will be covering this is a later post

F#20 : Creating Types / Adding Members

We now start the OO leg of our F# journey, where we will look at how to create classes (generic classes too) and use OO things like inheritance/interfaces, and we shall also look at how to use events within our classes, and how to use reflection to do meta programming against our classes instances.

 

Creating Types

We have already seen a few example of types being created on our journey so far, is may have passed you by which is fine, so here are a few ground rules when creating custom types

  • Types MUST live in a module
  • Types that do not contain any constructors/members at all, that are just marker classes MUST use the class/end class syntax

Let’s have a look at these 2 points in a bit more detail shall we.

So for point 1, what does that really mean? So if I have some code like the example shown below, is it valid? The answer is no….And why is the answer no? Well it is due to the fact the Person type is declared within the main method, which is not valid. As previously stated a type must be declared in a module, so to fix this we simply need to move the type to a dedicated module. That would fix point 1.

image

The next point from the above list means that you are not really allowed to do this, this is not a valid type definition, as it doesn’t contain any members

image

This is easily rectified using the class/end class syntax, which can be used just like this. Remember you ONLY need this if you want to create some sort of marker class, I don’t know how often you would like to do this, but if you do this is how you would do it

image

Constructors

In F# there is always a primary constructor which follows the types name which takes the arguments that are used to create an instance of the type. The primary constructor may contain let and do bindings, which according to MSDN work this way:

The let and do bindings in a class definition form the body of the primary class constructor, and therefore they run whenever a class instance is created. If a let binding is a function, then it is compiled into a member. If the let binding is a value that is not used in any function or member, then it is compiled into a variable that is local to the constructor. Otherwise, it is compiled into a field of the class. The do expressions that follow are compiled into the primary constructor and execute initialization code for every instance. Because any additional constructors always call the primary constructor, the let bindings and do bindings always execute regardless of which constructor is called.


Fields that are created by let bindings can be accessed throughout the methods and properties of the class; however, they cannot be accessed from static methods, even if the static methods take an instance variable as a parameter. They cannot be accessed by using the self identifier, if one exists.

http://msdn.microsoft.com/en-us/library/dd233205.aspx

Types may also have other constructors that MUST call the primary constructor, this is easily done using the new keyword which may be an empty constructor, or may take arguments.

Here is an example of a type that has 3 constructors

// The class's primary constructor takes two arguments: firstName and lastName, 
//both of type 'string'. 
type public Person(firstName : string, lastName : string) = 
    /// The fullName of the Person, computed when the object is constructed
    let fullName = String.Format("{0} {1}",firstName, lastName)

    //2nd constructor
    new() = Person("", "")
    //3rd constructor
    new(firstName : string) = Person(firstName, "")

    // 'this' specifies a name for the object's self identifier.
    // In instance methods, it must appear before the member name.
    member public this.FirstName = firstName
    member public this.LastName = lastName
    member public this.FullName = fullName

Which can be used as follows:

let p1 = new Person("sacha","Barber")
let p2 = Person("sacha","Barber")
let p3 = new Person()
let p4 = new Person("Steve")

do printfn "p1 = FirstName=%A, LastName=%A, FullName=%A" p1.FirstName p1.LastName p1.FullName
do printfn "p2 = FirstName=%A, LastName=%A, FullName=%A" p2.FirstName p2.LastName p2.FullName
do printfn "p3 = FirstName=%A, LastName=%A, FullName=%A" p3.FirstName p3.LastName p3.FullName
do printfn "p4 = FirstName=%A, LastName=%A, FullName=%A" p4.FirstName p4.LastName p4.FullName

Which when run gives the following output

image

Dependant Types

In one of the posts we already covered we saw how to deal with dependant types, that is Type A depends on Type B, and Type B depends on Type A. Here is an example of the problem:

image

In order to do that we can just loose the dependant type keyword, and replace it with the and keyword, which if you recall was done like this:

type Person(manager :Manager) =
    member this.Manager = manager
and Manager(name:string) = 
    let underlings = new List()
            
    member this.Underlings =  underlings    

For more information on this particular subject you can read the other post :

sachabarbs.wordpress.com/2014/04/09/f-15-code-organization-modules-files-types/

Adding Members

To add members to a type you just need use the self identifier followed by the period then a name. Members belong to an instance, not the type. Here is a trivial example of a “PrettyPrint” method, which has been added to our on going example

// The class's primary constructor takes two arguments: firstName and lastName, 
//both of type 'string'. 
type public Person(firstName : string, lastName : string) = 
    /// The fullName of the Person, computed when the object is constructed
    let fullName = String.Format("{0} {1}",firstName, lastName)

    //2nd constructor
    new() = Person("", "")
    //3rd constructor
    new(firstName : string) = Person(firstName, "")

    // 'this' specifies a name for the object's self identifier.
    // In instance methods, it must appear before the member name.
    member public this.FirstName = firstName
    member public this.LastName = lastName
    member public this.FullName = fullName

    member this.PrettyPrint() =
        printfn "FirstName %s, LastName %s" this.FirstName this.LastName |> ignore

 

Which we can use like this:

let p1 = new Person("sacha","Barber")
printfn "let p1 = new Person(\"sacha\",\"Barber\")"
printfn "p1.PrintyPrint()"
do p1.PrettyPrint() 

Which gives us this result:

image

Static Members

You may also add static members to a class which is done as follows:

Just like in any other .NET language a static member belongs to the type and not the instance, so to use it we simply use the type name followed by the member name. Here is the same demo class we have been building up, with a static “LastNameFormat” method which returns a tuple of the passed in firstName and LastName reversed:

// The class's primary constructor takes two arguments: firstName and lastName, 
//both of type 'string'. 
type public Person(firstName : string, lastName : string) = 
    /// The fullName of the Person, computed when the object is constructed
    let fullName = String.Format("{0} {1}",firstName, lastName)

    //2nd constructor
    new() = Person("", "")
    //3rd constructor
    new(firstName : string) = Person(firstName, "")

    // 'this' specifies a name for the object's self identifier.
    // In instance methods, it must appear before the member name.
    member public this.FirstName = firstName
    member public this.LastName = lastName
    member public this.FullName = fullName

    member this.PrettyPrint() =
        printfn "FirstName %s, LastName %s" this.FirstName this.LastName |> ignore

    static member LastNameFormat(f: string, l: string) = (l,f)

Which we make use of like this:

let p1 = new Person("sacha","Barber")

printfn "let p1 = new Person(\"sacha\",\"Barber\")"
printfn "Person.LastNameFormat = %A"  (Person.LastNameFormat(p1.FirstName, p1.LastName))

Which gives this result:

image

Adding Properties

There are 2 main areas that we need to cover when talking about properties:

  • Get only properties
  • Get and (possibly private) set

 

For immutable properties the syntax is simple we can simply do something like this:

type foo(name) =
    member this.Name = name

For mutable properties it gets a little more complex, where we have the following sort of syntax:

type foo(name) =
    // myName is private
    let mutable myName = name

    member this.MyName
        with get() = myName
        and set(value) = myName <- value

TIP : To make a set private you can use “private set” instead

From VS2012 onwards F# supports auto properties, which you can use to simplify your code, here are some examples of how you can use that.

type foo(name: string, age:int) =

    //immutable property
    member val MyName = name

    //mutable property
    member val Age =  age with get, set

Access Modifiers

In F# you do not have the full gamut of access modifiers you may be used to if you are coming from C#, you are limited to:

public : indicates the entity can be accessed by all callers

internal : indicates the entity can be accessed only by the same assembly

private : indicates the entity can be accessed only from the enclosing type of module

Access modifiers can be applied to modules, types, methods, value definitions, functions, properties and explicit fields

  • Access modifiers are generally put in front of the name of the entity. If no access modifier is used the default is public except in the case of let bindings in a type, which are always private to the type.

 

F#19 : Exceptions

In this post we will look at how to handle exceptions. We will be covering the following areas

  • Using the standard F# helper functions
  • Try With
  • Try Finally
  • Raising Exceptions
  • Reraising Exceptions
  • Custom Exceptions

 

 

FailWith

Probably the easiest path into Exception handling in F# is by using the helper function “failwith”, which when used produces pre-canned Microsoft.FSharp.Core.FailureException where your code is able to supply the Exception message. Here is an example of how to use this:

let divideByZeroFailwith x y =
    if (y = 0) then failwith "Oh no can't divide by zero silly"
    else
    x / y

let result1 = divideByZeroFailwith 10 0

If you run this code though you will see an issue, can you spot it?

So we just said the failwith helper function raises a new Microsoft.FSharp.Core.FailureException but this code doesn’t catch the exception so this code as it stands would cause the application to crash, as shown below.

image

So what do we need to do to fix this? Simply really we just need to catch the exception. Here is the same code refactored to catch the exception.

let divideByZeroFailwith x y =
    if (y = 0) then failwith "Oh no can't divide by zero silly"
    else
    x / y

try
    divideByZeroFailwith 100 0
with
    | Failure(msg) -> printfn "%s" msg; 0

Which when run gives the following output:

image

 

We will be looking at catching Exceptions in detail later in this blog.

 

InvalidArg

F# also comes with another helper function for raising an System.ArgumentException, which is the “invalidArg” function, which you can see an example of shown below.

This example allows the calling code to get an element value from a list using an index position, but if the requested index position is out of bounds (I am naively only checking the lower bound) we will get a System.ArgumentException thrown thanks to the usage of the invalidArg function

This example goes a little bit far for right now, but it does show you how you can catch a certain type of Exception, and get its message out within the with block. As I say we will be looking at this in this blog post, so don’t panic just yet if you do not get what the “| :?” syntax is doing.

let getListItem index (theList :int list) =
    if index < 0
        then invalidArg  "index" "Index is out of range"
    List.nth theList index

try

    //should work
    let result = getListItem 2 [1..10]
    printfn "result was %A" result

    //should not work, argument out of bounds
    let result = getListItem -1 [1..10]
    printfn "result was %A" result

with
    | :? System.ArgumentException as ex -> printfn "%s" ex.Message;

When run this produces the following output

image

 

 

Try With

In F# we can use the “try..with”expression to handle exceptions. One thing to note is that the “try..with” expression returns a value. Frequently, the fact that an error occurred also means that there is no valid value that can be returned from the expressions in each exception handler. As such a lot of people will use an option type. The option type MUST be the same type as the one in the try block. Here is an example

let optionReturningDivide x y =
    try
    Some( x / y )
    with
    | :? System.DivideByZeroException as ex -> printfn "Exception! %s " (ex.Message); None

let printIt opt =
    match opt with
    | Some(i) ->  printfn "Result was %A" i
    | None -> printfn "It was bad"

let resultGood = optionReturningDivide 10 2
do printIt resultGood    

let resultBad = optionReturningDivide 10 0
do printIt resultBad

Which when run gives the following results:

image

 

There are a couple of points to note in this latest snippet, which are

  • We used an Option type as the return value from a function that had a try..with block in it, which allows us to return a “Good value i.e. : Some(..)” or a “Bad value i.e. : None”, which can be pattern matched against by the caller
  • That we used the “| :?” syntax again. This is a pattern match used with a cast operator to cast the exception to a known type.

 

The first of those points should make sense, since we have covered option types and pattern matching, but the second point, may need a bit more explaining.

So when you have used a try..with block you are able to filter out what type of exception you want to deal with. Exceptions may be .NET exceptions or F# exceptions (which are created using the F# exception keyword, more on this later). Generally speaking this table tells you what you can do with filtering exceptions in F#.

 

Pattern Description
? exception-type Matches the specified .NET exception type.
:? exception-type as identifier Matches the specified .NET exception type, but gives the exception a named value.
exception-name(arguments) Matches an F# exception type and binds the arguments.
identifier Matches any exception and binds the name to the exception object. Equivalent to :? System.Exception as identifier
identifier when condition Matches any exception if the condition is true.

We have already covered a couple of items in that table in the examples we have seen so far, and we should see an example of one or 2 more of them by the time we finish this post.

 

 

 

 

Try Finally

The try..finally expression allows you to run code even if a block of code throws an exception. Here is a trivial example

let someArbitaryFinallyFunction x y =
    try
            x / y
    finally
        printfn "finally called in someArbitaryFinallyFunction" |> ignore

let getResult x y =
    try
        Some(someArbitaryFinallyFunction x y)
    with
        | :? System.DivideByZeroException as ex -> printfn "Exception! %s " (ex.Message); None

printfn "(getResult 10 2)  = %A\r\n" (getResult 10 2)
printfn "(getResult 10 0)  = %A\r\n" (getResult 10 0)    

Which gives the following output:

image

 

One common area where you may want to use try..finally is to handle the disposal of a resource. Here is an example of that

 

let writeToFileTest =
    let stream : System.IO.FileStream = System.IO.File.Create("test.txt")
    let writer : System.IO.StreamWriter = new System.IO.StreamWriter(stream)
    try
        writer.WriteLine("in the file")
    finally
        writer.Flush()
        printfn "Closing stream"
        stream.Dispose()

 

Although not directly related to try..finally, since we just talked about IDisposable it seems like it may be an ok place, so show an example or 2 of alternative approaches you could use in F# for handling IDisposable types.

The first way is by using the use binding, which is similar to the let binding but adds a call to dispose on the value when the value goes out of scope.

let writeToFileTest =
    use file1 = File.CreateText("test.txt")
    file1.WriteLine("in the file")

 

Another way is to use the using function. Which works much the same as it does in C#, the only difference is that in F# the disposable value becomes an input parameter to a lambda. At the end of the lambda the runtime calls the dispose method for you. Here is an example

let writeToFileTest =
    using(File.CreateText("test.txt"))
        (fun theFile -> theFile.WriteLine("in the file"))

 

Sorry about that slight off topic discussion, it just seemed to fit quite well with the current try..finally discussion, so apologies again for slipping that in there.

 

 

Combining Try..With / Try..Finally

The try with and try finally are separate, and can’t be created as a single statement, you are however free to nest them as your requirement dictate. Here is a small example:

let printIt opt =
    match opt with
    | Some(x) -> printfn "Result was %A" x
    | None -> printfn "None"

let optionReturningCombinedTryWithFinallyDivide x y =
    try
        try
            Some( x / y )
        with
            | :? System.DivideByZeroException as ex -> printfn "Exception! %s " (ex.Message); None
    finally
        printfn "I am the finaly block" |> ignore

let resultGood = optionReturningCombinedTryWithFinallyDivide 10 2
do printIt resultGood    

let resultBad = optionReturningCombinedTryWithFinallyDivide 10 0
do printIt resultBad

Which when run produces this output

image

 

 

 

Raising Exceptions

You can also raise exceptions using the raise function, which can be applied to .NET Exceptions and F# custom exceptions. Here is a small example

let printIt opt =
    match opt with
    | Some(x) -> printfn "Result was %A" x
    | None -> printfn "None"

let raisingFunction x y =
    if y = 0 then raise (new DivideByZeroException("y was zero, not going to work"))
    else
        Some( x / y )

let consumingFunction x y =
    try
        let resultGood = raisingFunction x y
        do printIt resultGood
    with
        | :? System.DivideByZeroException as ex ->
            printfn "Handled %s " (ex.Message);

do consumingFunction 10 2
do consumingFunction 10 0

Which when run gives the following output:

 

image

 

 

 

Reraising Exceptions

 

Another very common thing you may want to do is to re-throw an exception. In C# this would be accomplished using “throw;” inside of catch block, if you wanted to preserve original stack trace. F# can do the same it is just that the way you do it is slightly different.

In F# you need to use the reraise function inside a catch block. Here is an example where we have a function that uses a try..with, but also uses the reraise() function to rethrow the exception that the outer (consuming function) deals with i its own try..with block.

 

let printIt opt =
    match opt with
    | Some(x) -> printfn "Result was %A" x
    | None -> printfn "None"

let reraisingFunction x y =
    try
        Some( x / y )
    with
        | :? System.DivideByZeroException as ex ->
            printfn "Inner handled %s " (ex.Message);
            //reraise() rethrows exception back ut again
            reraise()

let outerHandler x y =
    try
        let resultGood = reraisingFunction x y
        do printIt resultGood
    with
        | :? System.DivideByZeroException as ex ->
            printfn "Outer handled %s " (ex.Message);

do outerHandler 10 2
do outerHandler 10 0

Which when run gives the following output:

image

 

 

Custom Exceptions

So far we have seen how to use the F# helper functions, and catch standard .NET exceptions, but what about when you want to create your own Exceptions, what choices do you have. Well you have 2 actually :

  • Inherit from the standard .NET exception classes such as ApplicationException etc etc
  • Use F# Exceptions.

It is the later point that the rest of this post will concentrate on, as we will cover inheritance in a later post n this series.

 

So how do we create and use our own F# exception types? Well it is actually pretty simple we just use the exception F# keyword, and then we can declare a new type  and treat it as a catchable exception. Here is an example:

This is how we declare a new F# exception type (see the exception keyword in use there). It can be seen that we can create this type exactly how we want to.

exception MyFSharpException1 of string * int

And here is the consuming code, notice the following:

  • We do NOT need to do the casting anymore, we can just deal with the F# exception how we would any other F# type and do cool things like pattern match its internal tupled structure. Neato
  • We were able to use the raise keyword to throw this exception type too, just as we did with the standard .NET ones
let printIt opt =
    match opt with
    | Some(x) -> printfn "Result was %A" x
    | None -> printfn "None"

let raisingFunction x y =
    if y = 0 then raise (MyFSharpException1 ("y was zero, not going to work",1))
    else
        Some( x / y )

let consumingFunction x y =
    try
        let resultGood = raisingFunction x y
        do printIt resultGood
    with
        | MyFSharpException1 (msg, failcount) ->
            printfn "Handled : msg : %A, Failcount: %A " msg failcount;

do consumingFunction 10 2
do consumingFunction 10 0

And this is what it looks like when it runs:

image

F#18 : Flow Control

As previously stated F# allows different styles of programming that is you can use of or all of the following:

  • Functional
  • Imperative
  • OO

In F# you have choices and you are free to mix and match these styles to suit your needs. In this article we will look at flow control statements, which although quite familiar still have a certain shall we say F#ness about them.

In this article we will be looking at the following flow control statements:

  • If Then Else
  • For
  • For..To
  • While..Do

If Then Else

You would have undoubtedly used If-Then-Else flow control expressions in many other languages. What differs in F# is that If Then Else is a statement and not an expression, and as such has certain rules associated with it, such as:

  • It must produce a value, which is the value of the last expression in the tree
  • The types produced in each branch must be the same
  • If there is no explicit else branch the return type is unit, which means if the type of the then branch is anything other than unit, you will need to provide a else branch
  • You may use the elif keyword to chain If Then Else together

Lets see some examples of this in action shall we:

From this example it can be seen that we do indeed need to provide the same types in both branches, otherwise we get a compiler error

image

And here we have another example where we have not supplied an else at all, so we must return unit, but we have broken this rule by attempting to return a string, which again gives us a compiler error

image

Here is the above example fixed with no compiler warnings:

let returnAString x  = if x then "cat" else "dog"

Here is an example that shows a if-elif-else combination.

let compareTheNumbers x y =
    if x = y then "=" 
    elif x < y then "<" 
    else ">"

printfn "%d %s %d" 10 (compareTheNumbers 10 20) 20
printfn "%d %s %d" 20 (compareTheNumbers 20 10) 10
printfn "%d %s %d" 20 (compareTheNumbers 20 20) 2

Which gives this output when run:

image

Sometimes a better approach would be to not use an If Elif Else at all, but rather use a standard pattern match. Here is an example where we have rewritten the last example but have changed it into a function that takes a tuple and uses pattern matching to achieve the same results as if we had of used a If Elif

let compareTheNumbers x =
    match x with
        | (x,y) when x = y -> "=" 
        | (x,y) when x < y -> "<" 
        | (_,_) -> ">"

printfn "%d %s %d" 10 (compareTheNumbers (10,20)) 20
printfn "%d %s %d" 20 (compareTheNumbers (20,10)) 10
printfn "%d %s %d" 20 (compareTheNumbers (20,20)) 20

For

This loop construct is used to iterate over an enumerable collection such as a list/sequence or array. It is similar to foreach in C#.

Here is an example

let sumTheList theList =
    let mutable total=0
    for i in theList do
        total <- total + i
    total
    
let theSum = (sumTheList [1..10])
printfn "The sum of [1..10] is %A" theSum

Though as before there are better (more functional) approaches one could take. For example we could use the many functions already existing in the list/sequence modules, which may alleviate the need to start using loops at all. Here is the above example rewritten using the the standard List module List.sum function.

let theSum = List.sum [1..10]
printfn "The sum of [1..10] is %A" theSum

 

For..To

It is also possible to do for loops to a certain end condition, and it is also possible to do for loops down to a certain end condition. Here is a small example which demonstrates both of these:

let forUpFunction() =
    printfn "for i = 1 to 10 do\r\n"
    for i = 1 to 10 do
    printf "%d " i
    printfn "\r\n" 

let forDownFunction() =
    printfn "for i = 10 downto 1 do\r\n"
    for i = 10 downto 1 do
    printf "%d " i

    
forUpFunction()
forDownFunction()

Which when run gives the following output

image

While..Do

F# also comes with a familiar While/Do loop construct, which you all would have seen/used in other languages.

Here is a trivial example that prints the index of a number within a source list. This is obviously just for demonstration purposes and you would not use this in real life, you would use List.find and that would be job done, I did however want to demonstrate a while/do loop, so please forgive me.

Here is the code:

let findANumberInAList theList theNum =
    let mutable index = 0;
    let mutable found=false
    let mutable current =0;
    let listHasItem = (List.exists (fun el -> el = theNum) theList)
    if listHasItem then 
        while not found do
            current <- List.nth theList index
            if(current = theNum) then
                printfn "Found %A in source list at index %A" theNum index
                found <- true
            index <- index + 1
                
let sourceList = [1..10]
printfn "SourceList = %A\r\n" sourceList
findANumberInAList [1..10] 4

Which when run produces the following output

image

F#17 : Mutable / Ref Cells

So in the last bog, we wrapped up a part of this series, which was to do with the functional programming aspect of F#. We will now begin the “Imperative Programming” section. This will not be a huge section and will not involve that many posts, and hopefully will be more familiar to people that may have come from C# or another .NET language, just like I have.

 

F# Standard Behaviour

The default behaviour in F# is for non mutable values. That it once a value has been bound, say using a let binding, you are not able to change its value. So if you try and assign a new value to the bound value, you will get a compiler error (that is unless you do one of the 2 things we are about to discuss below):

image

There are of course ways to make things mutable in F#, and this really comes down to 2 different approaches:

  1. Mutable
  2. Ref cells

We will be looking at both of these approaches

 

Mutable

As we just saw we can not update a non mutable value. What F# does allow us to do in this case, is to simply use a mutable keyword, which makes the value that it is used against mutable.

Here is the previous example rewritten to use the mutable keyword:

let mutable x = 10;
printfn "before x was %A" x
x <- 34
printfn "now x is %A" x

Which when run gives the following output:

image

 

You may use the mutable keyword in a number of different places, such as

  • Records
  • Types

Though there are some limitations when working working with mutable values, one that I have read about a bit ,is that local mutable values may not be captured by closured, and this is where Ref cells are preferred. This comes from Tomas Petricek, who outside of Dom Syme, is probably the most knowledgeable F# guy on the planet, so I think its a fairly safe bit of information to trust.

 

 

Ref Cells

MSDN says this about Ref Cells. “Ref Cells are storage locations that enable you to create mutable values using reference semantics.” Which is pretty much how I would have said it, so fair play MSDN thanks. You can kind of think of ref cells of a sort of pointer type idea, as you may find in C/C++ which support referencing and dereferencing. Though in F# we do not need to resort to using actual pointers. Another quite familiar thing is that you may see things like byref, which you may see in other languages such as C# where it uses the ref keyword. They are equivalent in C# you use ref to state you want something passed by reference, whilst in F# the keyword is byref, but they do the same job.

 

Declaring And Dereferencing Ref Cells

To declare and dereference a ref cell is quite easy, all we need to do is something like the following:

let theRefValue = ref 6
printfn "theRefValue before = %A" theRefValue.Value
theRefValue := 24
printfn "theRefValue after = %A" theRefValue.Value
let deRef = !theRefValue
printfn "deRef = %A" deRef

Where the following can be seen:

  1. We use the ref keyword to declare a ref value
  2. We use the assignment operator “:=” to assign a new value to the ref cell
  3. We use the dereference operator “!” which gets us the value of the ref cell
  4. That we made use of a Value property, which allows us to get the value of a ref cell

 

When we run the above code we will get something like this:

image

 

Helper Properties

Ref cells also come with a couple of handy properties, such as

  • contents
  • Value

Both of which are get/set, so you can use them to set the ref cell value. Here is an example:

let theRefValue = ref 1
printfn "theRefValue before = %A" theRefValue.Value

theRefValue.contents <- 2
printfn "theRefValue after theRefValue.contents <- 2 = %A" theRefValue.Value
   
theRefValue.Value <- 3
printfn "theRefValue after theRefValue.Value <- 3 = %A" theRefValue.Value

Which when run will give the following results:

image

 

Asking For A Ref Cell Parameter

Another thing you may want to do is demand that a certain function require a ref cell. This is done using the byref keyword (ref keyword in C#). When you use this keyword in F#, you must either pass a ref cell, or the address of one. The address of one is achieved using the “&” operator, like it is in C++.

Here is an example where I have written a function that requires a byref value. It can be seen that the 1st example usage does not give us what we want as it is not a ref cell.

open System
 module DemoTypes =
    type ChangeORama(newValue) =
        //We need caller to either pass a ref cell or address of one
        member this.Change(orig : string byref) =
            orig <- newValue


......
......
let changer = new ChangeORama("changed")

// Use a mutable but mutable isnt a ref cell, so should see no change
let mutable original ="I  like F#"
printfn "original = %A" original
changer.Change(ref original)
printfn "original using ref = %A\r\n" original

//Use address of Original this time, we should see change
let mutable original2 ="I  also like C#"
printfn "original2 = %A" original2
changer.Change(&original2)
printfn "original2 = %A\r\n" original2

//Use an actual refcell, which is then dereferenced, we should see change
let original3 = ref "I still like F#"
printfn "original3 = %A" original3
changer.Change(original3)
printfn "original3 using ref/deref = %A" !original3

 

Which when run gives us this result:

image

F#16 : Understanding Signatures

We are nearing the end of one of the main sections of this function series, but we have yet to look at one of the main elements you will see when using F#, which is signatures of functions.

In order to understand function signatures we will be revisiting our own old friend the “FSI Window”. We will start with some simple examples and then build up to more complex cases. So without further ado let’s begin.

 

The Basics

Unit : Unit is essentially void, and is expressed using the notation “()

-> : Is the separator between the parameter, and the last arrow will point to the return value

Tuples : Are expressed using the familiar notation (x * y)

Functions : Are wrapped in “(..)” parentheses

 

 

Understanding Functions That Taken No Parameters

We will start with functions that take no parameters at all, and return values.

 

Returning A Int

let aSimpleIntegerFunction() = 12

Gives us this type definition

  • aSimpleIntegerFunction : unit –> int

What that means is that the function takes unit (void) and returns an int

 

Returning A String

let aSimpleStringFunction() = "cat"

Gives us this type definition

  • aSimpleStringFunction : unit -> string

What that means is that the function takes unit (void) and returns an string

 

Returning A Bool

let aSimpleBoolFunction() = true

Gives us this type definition

  • aSimpleBoolFunction : unit -> bool

What that means is that the function takes unit (void) and returns an bool

 

Returning A Tuple

let aSimpleTupleFunction() = (1,"one")

Gives us this type definition

  • aSimpleTupleFunction : unit -> int * string

What that means is that the function takes unit (void) and returns an tuple of int and string

 

Returning A Record

type SimplePerson = { Name     : string; }
.....
let aSimpleRecordFunction() = { Name = "Alf" }

Gives us this type definition

  • aSimpleRecordFunction : unit -> SimplePerson

What that means is that the function takes unit (void) and returns a SimplePerson record type

Returning A List

let aSimpleListFunction() = [1,2,3]

Gives us this type definition

  • aSimpleListFunction : unit -> (int * int * int) list

What that means is that the function takes unit (void) and returns a list with 3 int elements in it. If we increased the size of the list returned by the function the signature would change accordingly

Returning A Sequence

let aSimpleSequenceFunction() = seq { 1..3}

Gives us this type definition

  • aSimpleSequenceFunction : unit -> seq<int>

What that means is that the function takes unit (void) and returns a sequence of int values

Returning A Function (Higher Order Functions)

In F# it is perfectly legal to return functions too. Any function that takes or returns another function is known as a Higher Order Function. Here is an example.

let doubleFunction x = x * 2
let aSimpleHigherOrderFunction = doubleFunction

Which gives us this type definition

  • aSimpleHigherOrderFunction : (int -> int)

Since our “aSimpleHigherOrderFunction” simply returns the original function “doublerFunction” it is that original function “doubleFunction” that is the one that is returned, and as such it is that functions signature that we see in the FSI window. So we get a function that takes an int and returns an int. As stated earlier functions are shown as “(“ and “)”, though watch out for tuple which also use braces, but they also use “*” so they should be easy to spot. They will take the form “(a *b)

While we are on the subject of Higher Order Functions, we should probably mention the more common use cases examples, which would likely involve one of the many functions available within the List/Sequence modules. For example List.Map, which has the type signature :

  • List.map : ('T -> 'U) -> 'T list -> 'U list

Which takes the following input parameters

A function that takes a generic parameter ‘T, and returns a new generic value ‘U

  1. Takes a list of generic values ‘T
  2. Which returns a new list of generic values ‘U

So lets see an example of this in action.

Here is a small example that will negate a list of numbers, where we declare a “negate” function that takes a value and returns a new value. So this will work with List.Map, as its type signature fits with what List.Map requires.

 

let negate x = -x
let newList = List.map negate [1;2;3;4]

We could of course make this a bit more succinct by using a lambda function, which would give us this:

let newList = List.map (fun x -> -x) [1;2;3;4]

 

Understanding Functions That Taken Parameters

Ok so we have now seen what return values look like, so lets start adding in some input parameters into the mix.

 

Generic Function

So let’s start with a generic function, where we let the F# type inference system decide what the type will be.

Here is the function we will be using:

let aSimpleGenericFunction x = ()

Which when inspected in the FSI Window gives us this type definition

  • aSimpleGenericFunction : x:'a –> unit

Which as you can see has a strange “ ’a “ type for the parameter named X. What is this, well in F# that is how generics are represented. So this function is completely generic as far as the input parameter goes, and simply returned unit “()

So since it is completely generic these are all valid calls to the function:

aSimpleGenericFunction 12
aSimpleGenericFunction "cat"
aSimpleGenericFunction true

 

Taking A Single Parameter

So what about when we don’t want to use generics and want to specify the type we want, how do we do that. Well we can do that as follows:

let aSimpleIntOnlyFunction (x : int) = ()

Which when inspected in the FSI Window gives us this type definition

  • aSimpleIntOnlyFunction : x:int -> unit

Which as you can is a function that takes a single int value, and simply returned unit “()

So since we have now locked down the type accepted as an input parameter to this function, we can’t pass in anything other than a single int value.

image

 

Taking Several Parameters

So how about we now look at taking a few parameters, for the sake of simplicity I will fix the types allowed. So here is an example:

let aMultipleParamsFunction (x : int) (y: string) = ()

Which when inspected in the FSI Window gives us this type definition

  • aMultipleParamsFunction : x:int -> y:string -> unit

Which as you can is a function that takes a int and a string value, and simply returned unit “()

 

Taking A Mix Bag Of Parameters

Ok so we now have the basics covered, lets mix it up a bit by looking at what you we get if we create a pretty full on function that takes a variety of the types we have looked as so far:

let theUberFunction (a : int option) (b : int list) (c : string) (d) = ()

Which when inspected in the FSI Window gives us this type definition

  • theUberFunction : a:int option -> b:int list -> c:string -> d:'a -> unit

Which as you can is a function that takes

  • A int option
  • A int list
  • A string
  • A generic type

And returns unit “()

Just for completeness here is what an example of calling this function looks like

theUberFunction (Some 12) [1;2;3] "dog"  { Name = "Alf" }

Taking Parameters And Having A Non Unit Return Value

So lets finish this section with a truly weird function, which looks like this:

let someCrazedFunction (a:int) (b:string) (c:SimplePerson) 
    (d: Collections.List<int>) (e) = (a,b,c,d,e)

Ok, I have gone a bit over the top with this one, but the point is it is still totally valid, and you may see things like this in the wild, although I do not think this is a great idea at all, we would likely tuple the parameters instead. Let’s continue though and see what the signature for this one looks like. The first 4 parameters should be pretty obvious, and the last one is a generic one, but what would the return value of this be? Lets find out.

  • someCrazedFunction :

      a:int ->

        b:string ->

          c:SimplePerson ->

            d:List<int> -> e:'a -> int * string * SimplePerson * List<int> * 'a

This looks a little nuts, but lets just break it down. From left to right (which is the correct way to read F# signatures)

This function is one that takes the following input parameters:

  1. An Int
  2. A String
  3. A SimplePerson record
  4. A list of Ints
  5. A generic value

And it returns a tuple of int * string * SimplePerson * List<int> * ‘a

I deliberately made this one a bit strange, so that we could see a somewhat weird signature

One To Watch Out For

You may on occasion see a function that includes a “inline” keyword.This F# keyword is used to integrate the function directly into the calling code. Here are some examples of where you might see inline used:

type WrapInt32() =
    member inline this.IncrementByOne(x) = x + 1
    static member inline Increment(x) = x + 1

...
...
let inline Increment x = x + 1 

The thing is, using the inline keyword, DOES effect the signature of a function, so that is why I am bringing this up in this blog post.

For example lets say I had this function

let PrintAsFloatingPoint number =
    printfn"%f" (float number) 

I think this would pretty easy to guess the signature of, it takes an ‘a generic, and the last line of the function is a printfn one, which returns Unit, that was my guess The actual signature is

  • PrintAsFloatingPoint : number:int –> unit

This is due to the F# tylpe inference system deducing a input type, in this case int.

 

But let’s see what happens when we use the inline keyword. So sticking with the same example:

let inline InlinePrintAsFloatingPoint number =
    printfn"%f" (float number) 

Which when examined in the FSI Window has the following signature, which is very very different:

  • inline InlinePrintAsFloatingPoint :  number: ^a -> unit when  ^a : (static member op_Explicit :  ^a -> float)

 

 

Using the inline keyword forces the F# type inference system to infer that the function can take a statically resolved typed parameter. This means that the function accepts any type that has a conversion to float. That is why we see the use of the “op_Explicit” and “^a –> float” (the ^a specifies types that must be resolved at compile time not at runtime) which makes sure it is convertible to float.

 

Interestingly enough if we actually lock down the type for the number parameter for both these demo functions to an int, so we have these new functions:

let PrintAsFloatingPoint (number :int) =
    printfn"%f" (float number) 

let inline InlinePrintAsFloatingPoint (number :int) =
    printfn"%f" (float number) 

 

And now look at the type signatures, we can see that they are identical.

  • PrintAsFloatingPoint : number:int –> unit
  • inline InlinePrintAsFloatingPoint : number:int -> unit

 

So beware inline may catch you out

 

F# 15 : Code Organization (Modules / Files/ Types)

Now that we have some of the basic types and pattern matching under our belts, I thought it high time that we learnt a bit about how to organize our own code. Throughout some of the posts we have already been through I have been referring to modules such as the “List module”. In this post we will see not only how to create our own modules but also why they are important. We shall also see how to organize files/type definitions, and see why this is important.

 

Organizing Types

Lets start with a simple example, as simple as it gets in fact, suppose we have this code (screen shot this time sorry)

image

It can be seen that we already have an issue. This is down to the fact that in F# any types/functions/values that are needed by the current type/function etc etc are needed to be defined before usage. This in stark contrast to C# say where this would have been totally fine:

void Main()
{
	var doubled = doublerFuction(12);
}


private int doublerFunction(int x)
{
	return x * 2;
}

This simple case is very easy to fix, we just need to swap the order of the lines in the F# code, so it would end up being like this:

image

Happy days, no more issues. That is however a very short term, and not very long sighted win. Surely there must be a better for us to organize our code in F#. Well yes there is.

Help comes in the form of files and modules.

 

Files

A file in F# is a simply a F# source code file, that may contain arbitrary code, it could contain a mixture of any of the following

  • functions
  • type definitions
  • let bindings
  • modules

But a F# file get special treatment by Visual Studio, an even comes with its own set of Visual Studio context menus. Which are shown right here:

image

 

Now you may be wondering why you would need to move files up and down. Well it is for the same reason the type definitions did not work earlier, the files have to be in a certain order too. That is to say if you have  a function declared in File2.fs that is needed by File1.fs, File2.fs MUST appear before File1.fs in the visual studio IDE.

The Visual Studio IDE even stops you from

  • adding new folders to projects
  • copy + past an existing file in the solution
  • dragging and dropping files to alter their positions in the solution

These things (like them or not)are done to encourage you to organize your F# files in a correct way.

We will see later on that this quite strict enforcements are not actually as bad as they seem, as we can use a few other organizational things to help us out such as:

  • Namespaces
  • Modules
  • A nice auto open feature

 

Modules

Modules in F# are a way to logically group functions/types and let bindings. According to MSDN it is implemented as a common language runtime (CLR) class that has only static members.

You can declare a module like this:

image

Which in actual code simply looks like this:

module SachaPrintingModule =
 
    let prettyPrint x = 
        printfn "The value of x is %A" x
 
    let somePrintFunction x = 
        prettyPrint x

A module can contain many types, and functions. It can even contain sibling / nested modules. Though it should be noted that as soon as your F# project grows beyond one file you will need to also include namespaces, but more on this later.

Here is an example of sibling modules which are within a single *.fs file (as I say this is only as long as you have less than 2 *.fs files in the project)

module SachaPrintingModule =
 
    let prettyPrint x = 
        printfn "The value of x is %A" x
 
    let somePrintFunction x = 
        prettyPrint x
 
 
module SachaRandomModule =
    let doublerFunction x = 
        x * 2

Well we have seen lots of example of using modules already such as List/Sequence/Print etc etc, but we have yet to see how to use our own. Well to use our own all we need to do is use the following syntax to import the types/functions contained within the module “open FULLY-QUALIFIED-NAME-OF-MODULE”, which once done will allow you to use the types/functions within the opened module. Here is a complete example for a F# project that contains a single F# file (again since it is a single F# file based project we can get away without including namespaces):

module SachaPrintingModule =
  
    let prettyPrint x = 
        printfn "The value of x is %A" x
  
    let somePrintFunction x = 
        prettyPrint x
  
  
module SachaRandomModule =
    let doublerFunction x = 
        x * 2
  
  
module MainModule = 
    open SachaPrintingModule
  
    [<EntryPoint>]
    let main argv = 
        somePrintFunction 12
        0 

The above example shows 2 sibling modules, and a main module (which has the main entry point for the project). The main module opens the “SachaPrintingModule” so it is then able to make use of the contained functions from the “SachaPrintingModule

 

Namespaces

Namespaces allow you to organize your code into related functionality by enabling you to add a name to a grouping of elements.  if you decide to use namespaces they must be the first element of a file, and everything else in the file will become part of the namespace.

Namespaces have a few rules such as:

  • They can not contain values and functions
  • They can contain types, and modules

 

So if you find you want to use more than types then you will need to start to look at namespaces that contain modules. As I have also stated, once you go past that magical limit of 1*.fs files, you will need to worry about namespaces too.

Though this sounds like a PITA it really isn’t that bad, all you need to do is add a namespace declaration and make sure to fully qualify your module imports with the namespace name where you need to import the module.

Here is an example of a couple of namespaced modules in a multi *.fs file project (this is the actual order they appear in within the project as well). As you can see File1.js /File2.js simply contain function definitions, whilst File3.js makes use of the File1.js and File2.js functions, which it does by opening the modules, where the module name is fully qualified.

The last file in the project Program.fs makes use of the File3.js functions, which as before it does by opening the module.

 

File1.fs

namespace ConsoleApplication1
    module SachasDoublerModule = 
        let doublerFunction x = x * 2

File2.fs

namespace ConsoleApplication1
    module SachasTriplerModule = 
        let triplerFunction x = x * 3

File3.fs

namespace ConsoleApplication1
    module SachasRandomModule = 

       open ConsoleApplication1.SachasDoublerModule
       open ConsoleApplication1.SachasTriplerModule

       let randomFunction x = (doublerFunction x) + (triplerFunction x) 

Program.fs

namespace ConsoleApplication1
    module MainModule = 
 
    open System
    open System.IO
    open System
    open System.Linq
    open System.Collections.Generic
    open ConsoleApplication1.SachasRandomModule
 
 
    [<EntryPoint>]
    let main argv = 
 
 
        //use the ConsoleApplication1.SachasRandomModule functions
        printfn "The random value of 2 is %A" (randomFunction 2)
 
        Console.ReadLine() |> ignore
        0 

AutoOpen

There is a special attribute that can help you with modules, which is the AutoOpenAttribute, which can be applied to modules, which makes the contents of the module available to other modules in the same namespace.

You can read more about this at MSDN : http://msdn.microsoft.com/en-us/library/ee353721.aspx

Here is the example we just looked at re-written to take advantage of the AutoOpenAttribute

File1.fs

This now makes use of the AutoOpenAttribute to share the module with anything in the same namespace:

namespace ConsoleApplication1
    
    [<AutoOpen>]
    module SachasDoublerModule = 
        let doublerFunction x = x * 2

File2.fs

This now makes use of the AutoOpenAttribute to share the module with anything in the same namespace:

namespace ConsoleApplication1
 
    [<AutoOpen>]
    module SachasTriplerModule = 
        let triplerFunction x = x * 3

File3.fs

See how this one no longer needs to open the ConsoleApplication1. SachasDoublerModule / ConsoleApplication1.SachasTriplerModule

namespace ConsoleApplication1
 
    [<AutoOpen>]
    module SachasRandomModule = 
 
       let randomFunction x = (doublerFunction x) + (triplerFunction x) 

I have not changed the Program.fs code, so that is as previously shown. This was just to show you that you could shared modules using the AutoOpenAttribute

Cyclic Dependencies

So far we have seen how we can use files/modules/namespaces to help us organize our code. However there is one final element I wanted to mention which is actual dependencies in our code. What I mean by that is what would happen if we had a type (say Person type) that depends on another type (say Manager type), and the Manager also depends on the person. That is what is known as a cyclic dependency, which when written down could look something like this:

image

 

As you can see from the screen shot above, the following hold true:

  • The Person type is not compiling as it has a dependency on the Manager type, which is doesn’t know about due to the position of the Manager type in the F# code file. Ok we could move the Manager type up, but then it would start complaining as it has a dependency on the Person type.
  • Right now the Manager type is ok, as Person is declared above it, so it knows about the Person type.

 

Mmmm what a pickle. What can we do about this. Luckily F# has a way out of this sort of thing, it is called the “and” keyword, which would allow us to write the above cyclic code in a non cyclic way. Here it is re-written using the “and” keyword:

 

namespace ConsoleApplication1
   
    [<AutoOpen>]
    module SachasDomain = 

        open System;
        open System.Collections.Generic;
        
        type Person(manager : Manager option, name : string) = 
            member this.Manager = manager  
            member this.Name = name
            override this.ToString() = 
                match this.Manager with
                | Some(Manager) -> String.Format("Person {0} has Manager {1}", 
                    this.Name, (Option.get(this.Manager).Name))  
                | None ->  String.Format("Person {0} has NO Manager", this.Name)
        //**********************************************
        // use the "and" keyword to break the cyclic dependency between
        // "Person" type and "Manager" type
        //**********************************************
        and Manager(name : string) = 

            let underlings = new List<Person>()
            member this.Underlings = underlings
            member this.Name = name



Which has this code that makes use the above code:

namespace ConsoleApplication1
    module MainModule = 

    open System
    open System.IO
    open System
    open System.Linq
    open System.Collections.Generic
    open ConsoleApplication1.SachasDomain
   
    [<EntryPoint>]
    let main argv = 

        let manager = Manager("manager1")
        let p1 = Person(Some(manager), "person 1")
        manager.Underlings |> ignore

        manager.Underlings.Add(p1)
        printfn "Manager %A has (%A) underlings\r\n" manager.Name (manager.Underlings.Count)

        let c = manager.Underlings.Count

        printfn "Person details\r\n%A" (p1.ToString())

        Console.ReadLine() |> ignore
        0




Which when run will give the following results:

image

 

Now as I stated at the very beginning of this series I am a mere fledgling when it comes to F#, I am not a guru at all. There is however a fabulous series of post by someone whom I do consider to be a F# guru, that person is Scott Wsaschin, who has a truly excellent F# blog http://fsharpforfunandprofit.com, I just wanted to draw your attention to these 3 posts in particular as Scott goes into some very nitty gritty detail about “cyclic dependencies” and how to get rid of them. If you are interested in learning more about F# and in particular “cyclic dependencies” you owe it to yourself to read these 3 posts:

  1. http://fsharpforfunandprofit.com/posts/cyclic-dependencies/
  2. http://fsharpforfunandprofit.com/posts/removing-cyclic-dependencies/
  3. http://fsharpforfunandprofit.com/posts/cycles-and-modularity-in-the-wild/