F# Generic Inlining With Member Constraints

by Marc Sigrist 13. July 2012 16:05

In this post, we are going to create a Converter class who converts values to strings. The conversion rules are specified by passing the name of a culture to the class’ constructor. The culture name can contain just the language (as ISO 639-1 alpha-2 code, e. g. “en”) or the language and region (as ISO 3166 code, e. g. “US”) combined with hyphen, e. g. “en-US”. An empty culture name “” specifies the invariant culture, which falls back to “en”.

The class has only one conversion method ToString, who is generic. It takes a single parameter, which is the value to be converted. The parameter’s type is inferred to have a member constraint, who restricts the type (at compile time) to have an instance member with the signature
ToString: IFormatProvider -> string. The parameter’s member is invoked with a member constraint invocation expression.

open System
open System.Globalization
 
type Converter(cultureName:string) =
    /// The culture used by this converter.
    member val Culture = CultureInfo.GetCultureInfo cultureName

    /// Converts value to a string, based on the specified culture.
    member inline self.ToString value =
        (^T: (member ToString: IFormatProvider -> string) 
        value, self.Culture)
 
// Test
let germanConverter = Converter "de"
let nrString = germanConverter.ToString 1234.643  // "1234,643"
let dtString = germanConverter.ToString <| 
               DateTime(2003, 11, 25, 17, 38, 47) // "25.11.2003 17:38:47"

Edit (Oct 15, 2012)

 The converter's culture is now exposed via a public property, based on F# 3.0 auto property syntax. (The Culture's value is evaluated only once, during class construction time.) Previously, the culture was a private field, and the example could not compile in a regular source file, due to access rule violation. Strangely, it did compile in a scripting file; this is an example where the scripting compiler (wrongly) does not behave in the exact same way as the regular compiler.

This is a blog post in the “Brief tip” category. It is meant as a starting point for further investigation, not as a complete copy/paste solution to a specific concern you may have.

"Super-Strong" Typing, Dynamic Typing, and Type Inference in F#

by Marc Sigrist 23. January 2012 15:19

This article gives an overview how types are accessed in F# with a combination of features related to static typing, dynamic typing, and type inference.

Static Typing

Static type checking ensures, at compile time, that the program is free from most kinds of type errors. The source code editor can highlight such errors as soon as they are written out. Static type checking in F# probably goes further than in any other strongly typed language:

  • By default, types defined in F# cannot be null. This eradicates a whole category of painful and costly errors (Tony Hoare of Microsoft Research Cambridge, who introduced null references in ALGOL in 1965, later regarded this as his "Billion dollar mistake").
      
    
  • Implicit conversions are not allowed. This even includes numeric, precision-preserving coercions. For instance, you cannot pass an integer, when a floating point value is expected, without explicit conversion. However, F# permits passing an argument of a derived type where a parameter of a base type is expected. It is also possible to utilize implicit operator overloads, who have been implemented in other languages, by calling the op_implicit member of the Common Intermediate Language (CIL) type:
      
    
    open System.Drawing
    let rect = Rectangle(23, 12, 17, 13)
    let rectF = RectangleF.op_Implicit rect
    
      
    
  • A new feature introduced by F#, units of measure, lets the compiler verify calculations associated with measurements. This prevents you from passing a number of meters when a number of kilograms is expected. On the other hand, when you multiply a number of meters with another number of meters, the compiler automatically creates type-safe square meters for you:
      
    
    [<Measure>]
    type m
    let meters = 276<m>
    let squareMeters = meters * meters
    // Resolved by the compiler as:
    // val squareMeters : int<m ^ 2> = 76176
    
      
    
    In F# 3.0, the core library will contain the namespace Microsoft.FSharp.Data.UnitSystems.SI, with predefined units of measure types for the International System of Units (SI), such as ampere (A), hertz (Hz), kelvin (k), lux (lx), metre (m), newton (N), second (s), ... Units of measure were originally conceived by Andrew Kennedy, of Microsoft Research Cambridge, in his PhD thesis. He also wrote a great introduction about it in his blog.
      
    
  • F# 3.0 will introduce another pioneering feature: type providers. They let you access any kind of untyped data source, locally or remotely, in a strongly-typed way at compile time, with full autocompletion/IntelliSense support. There will be built-in type providers for database connections, OData services, web services, resource files, and more. You will also be able to create your own custom type providers.

Dynamic typing

With type providers, there is no more need for dynamic typing... almost! For instance, one may still require dynamic typing for calls to arbitrary, untyped data sources unknown at compile time. In F#, this can be achieved by implementing the predefined dynamic operators ? and ?<-. These operators permit, with almost "surgical precision", to access parts of a type in a "weak" (but generic) way, while still keeping the "strong" access to the rest of the type's API intact.

// Implement dynamic operators for System.DataRow 
// to allow getting/setting a generic value.
open System.Data
let (?) (row:DataRow) (columnName:string) = 
    unbox row.[columnName]
let (?<-) (row:DataRow) (columnName:string) value  = 
    row.[columnName] <- value

// Create a DataTable with two columns.
let table = new DataTable()
table.Columns.Add("Name", typeof<string>)
table.Columns.Add("Born", typeof<DateTime>)

// Initialize a DataRow, using the dynamic operator.
let row = table.NewRow()
row?Name <- "John Doe"
row?Born <- DateTime(1983, 7, 26)
table.Rows.Add row

// Read the row content into a strongly-typed record.
type Person = {Name: string; Born: DateTime}
let record = {Name = row?Name; Born = row?Born}

I find this approach preferable to C#, whose dynamic keyword is less granular, as it forces the programmer to access the complete API of a type in a weak way. It is also non-generic, as each access to a dynamic instance returns another dynamic instance.

Type inference

Type inference in F# automatically recognizes the intended types (including generic types) of local values, parameters (including return parameters), and let-bound fields. Is is based on the Hindley–Milner (HM) method. One can always declare a type manually, in various places in the source code. However, declaring a type is usually not necessary. As a consequence, you can write straightforward, simple code, even when the types and signatures involved are highly generic. The following example creates a helper class in F#, which may be used by any client written in a CIL-compatible language (F#, C#, VB.Net, ...).

open System.Linq
type SortHelper =
    static member GetTopN(values, keySelector, n) =
        Enumerable.OrderByDescending(values, keySelector) |> Seq.take n 

The above GetTopN method looks as follows when accessed from C#. Notice how the F# compiler has automatically inferred the types and genericity of the signature from the context:

public static IEnumerable<a> GetTopN<a, b>
    (IEnumerable<a> values, Func<a, b> keySelector, int n)
  

Conclusion

The combination of static typing, dynamic typing, and type inference gives you the best of three worlds. Static typing with type inference has been known for many years in functional languages such as Haskell and functional/object-oriented languages such as OCaml. However, with units of measure and type providers, F# gives you a new kind of "super-strong typing", while still allowing weak typing in cases where it is unavoidable. In addition, F# gives you type-safe access to thousands of types predefined in the .NET Framework (or Mono), and—via CIL interoperability—to a potentially unlimited number of libraries implemented in other languages.

Tags:

F#

List-like expressions in F# 2.0

by Marc Sigrist 16. July 2011 13:13

F# provides literal expressions for tuples, F# lists, arrays, enumerables, and other generic types. The elements of a tuple expression are separated by commas. The elements of all other kinds of list-like expressions are separated by semicolons.

F# Expression F# Type Representation C# Type Representation
17, 3, 8   
int * int * int
Tuple<int, int, int>
[17; 3; 8]
int list
FSharpList<int>
[|17; 3; 8|]
int[]
int[]
seq {yield 17; yield 3; yield 8}
int seq
IEnumerable<int>

Note that F# lists should not be exposed to non-F# programs, because languages such as C# do not have the necessary language constructs for a smooth coding experience (:: operator, pattern matching, etc.).

The expressions can be nested deliberately.

F# Nested Expression F# Type Representation C# Type Representation
[17, 3, 8]
(int * int * int) list
FSharpList<Tuple<int, int, int>>
[|17, 3, 8|]
(int * int * int)[]
Tuple<int, int, int>[]
[|[|17; 3; 8|]; [|5; 2|]|]
int[][]
int[][]
array2D [[1; 5]; [7;9]]
int[,]
int[,]
[|array2D [[1; 3]; [1; 3]]|]
int[,][]
int[][,]
[|2.7M, true; 3.9M, false|]
(decimal * bool)[]
Tuple<decimal, bool>[]
(1, 'c'), (3.3, 20I, "abc")
(int * char) *
(float * bigint * string)
Tuple<Tuple<int, char>, 
Tuple
<double, BigInteger, string>>
Etc.
   

Note that in F#, jagged multidimensional arrays are represented in reverse order compared to C#: The F# type int[,][] corresponds to the C# type int[][,]. This is to keep it consistent with other F# postfix type names, such as int option list, an example of which would be [None; Some(1); Some(2)].

Instead of using semicolons, one can put each element on its own line, as in this array of type int[]:

[| 17
   3
   8 |]

F# contains many more kinds of expressions to simplify working with list-like types. The following range expression defines an IEnumerable<decimal> from 3 to 1275, with steps of 0.25 in between: 3, 3.25, 3.50, 3.75...

seq { 3M .. 0.25M .. 1275M }

The following code defines an array of type int[] with squares of positive whole numbers: 1, 4, 9, 16, ...

[| for i in 1 .. 1000 -> i * i |]

All the list-like types in F# are supported by a wealth of keywords, symbols and operators, and helper functions in FSharp.Core.dll. The following code defines an "infinite" IEnumerable<UInt64> of binomial results, calculated from each consecutive pair of natural numbers starting at zero: 1, 9, 25, 49, ...

Seq.initInfinite uint64
|> Seq.pairwise
|> Seq.map(fun (a, b) -> pown (a + b) 2)

Further information on list-like expressions in F# can be found in the F# 2.0 Language Specification and Visual F# documentation.

Tags:

F#

Covariance and Contravariance in C# 4.0

by Marc Sigrist 20. March 2011 02:07

C# 4.0 allows to declare variance compatibility for delegates and interfaces. This means, for instance, that one can assign an IEnumerable<Cat> to an IEnumerable<Animal>.  The term variance compatibility, in this context, defines the kind of assignment compatibility between two closed generic types, which exists when the parameters of those types are derived from each other (or are themselves variant to each other). In other words: Given two types T1<P1> and T2<P2>,  variance defines how T1 is assignment compatible with T2 in cases where P1 is in an inheritance relationship with P2 (or is itself variant to P2). A more detailed definition can be found in the C# 4.0 language specification, section 13.1.3 Variant type parameter lists. There are three kinds of variance:

Kind of Variance Delegate Example Interface Example
Invariance
delegate T Clone<T>(T t);
interface IList<T>{
    T this[int index] { getset; }
    // Etc.
}
Covariance
delegate T Func<out T>();
interface IEnumerator<out T>{
T Current { get; }
};
Contravariance
delegate void Action<in T>(T t);
interface IComparer<in T>{
int Compare(T x, T y);
}

Invariance

In the above table, Clone<T> and IList<T> are invariant in T. As a consequence, it is not possible to assign Clone<Dog> to Clone<Animal>, or vice versa. This is because T is used both as an incoming parameter and an outgoing parameter at the same time. Imagine what would happen if one could actually assign an IList<Dog> to an IList<Animal>. If we then retrieved animals[0], we would get a dog as animal. So far, so good. However, what would happen if we set animals[0] = new Cat()? What should the underlying IList<Dog> do when it gets the cat assigned? Should it perhaps throw an InvalidCastException? There is no way this can be handled without violation of the strong typing principle. Therefore, the core languages of the .Net Framework: C#, F#, and VB.NET (with option strict on) do not allow covariance or contravariance in this situation.

IList<Animal> animals = new Collection<Animal>();
IList<Cat> cats = new Collection<Cat>();
// The following line would produce a compiler error.
// animals = cats;
// Thanks to the above compiler error, we can always be sure
// that the following line will not produce a runtime exception.
animals.Add(new Dog());

Unfortunately, ever since C# 1.0, strong typing has not been completely enforced with regards to arrays (many other languages, e.g. Java, have the same problem). The following programming error is not prevented by the compiler:

Cat[] cats = { new Cat(), new Cat() };
Animal[] animals = cats; // Compiler allows covariance, eventhough in parameters exist.
animals[0] = new Dog(); // --> ArrayTypeMismatchException at runtime!

Here is an interesting side note: It is sometimes argued that breaking type safety with arrays was a planned, pragmatic decision at the time of C# 1.0, because generics did not exist yet. However, according to Don Syme, who was responsible for generics in the CLR, back then it was not even certain whether generics would ever be introduced at all. Microsoft was reluctant, and the responsible research team was underfunded. The feature could only be introduced in C# 2.0 under extreme pressure at the very last minute. Luckily, things are different now. Runtime-integrated generics, and the many technologies built open them (such as Lambda expressions, Linq, and F#), have become a great success story, and they clearly distinguish Microsoft .Net and Mono from other popular development frameworks.

Covariance

In the above table, Func<out T> and IEnumerator<out T> are covariant in T. As a consequence, it is possible to assign Func<Cat> to Func<Animal>. Strong typing can be enforced by the compiler, because T is only used as outgoing parameter, never as incoming parameter. To enable covariance in T, T must be explicitly annotated with the generic modifier out.

Func<Animal> createAnimal = () => new Animal();
Func<Cat> createCat = () => new Cat();
createAnimal = createCat;
var a = createAnimal(); // Gets a cat as animal.

Contravariance

In the above table, Action<in T> and IComparer<in T> are contravariant. Therefore, it is possible to assign Action<Animal> to Action<Cat> or IComparer<Animal> to IComparer<Cat>. Strong typing can be enforced by the compiler, because T is only used as incoming parameter, never as outgoing parameter. To enable contravariance in T, it must be explicitly annotated with the generic modifier in.

Action<Animal> animalAction = animal => animal.Sleep();
Actionn<Cat> catAction = cat => cat.Meow();
catAction(new Cat()); // Meow...
catAction = animalAction;
catAction(new Cat()); // Zzz...

Other Considerations

Classes and structs cannot be declared as covariant or contravariant. Even if such a syntax were allowed, the feature would be useless in most cases. For instance, it would be logically impossible to assign a Collection<Cat> to a Collection<Animal>, because Collection<T> uses T both as an incoming parameter and an outgoing parameter. Every kind of collection, even if it is immutable, somehow needs a way to be built up (using T as incoming parameter) and a way to be read from (using T as outgoing parameter). Still, in some cases, where T is used only as incoming parameter or only as outgoing parameter, the feature might be practical (imagine some kind of Builder<out T> or Deserializer<out T>). However, the complexity of the C# compiler is stunning already today. For instance, given something as simple as an interface I1<out T>, it has to enforce type safety for extreme situations like I1<I1<I1<I2<I1<Pet>, I3<I2<Dog, I1<Cat>>>>>>>. But even if it can be proved that it is theoretically possible to create a compiler for C# who is sophisticated enough to check type safety for covariant or contravariant classes, it still does not necessarily make sense to spend the immense amount of time and resources it takes. Rather than doing this, I would prefer Microsoft to implement other features for the language, who take less effort, but are more urgent, such as read-only local "variables", an internal protected access modifier (as opposed to protected internal), and (my favorite wish) non-nullable reference types (if we have int? i, why not also have string! s? :)

I have covered the basics about variance in C#, the rest can mostly be concluded by logical deduction and combination (e.g., dealing with ref and out method parameters, etc.). However, if you truly want to dive into the matter, I recommend Eric Lippert's (of the C# compiler team) excellent twenty-one-part blog series on the subject.

Calculating a range of arbitrarily large prime numbers in F# 2.0

by Marc Sigrist 15. November 2010 20:30

The library System.Numerics.dll, who was introduced in .Net 4.0, contains a System.Numerics.BigInteger structure. BigInteger represents a whole number of arbitrary size (or precision). Before .Net 4.0, the largest number that could be represented "out of the box" was System.Double.MaxValue. Written in decimal notation, this would be a whole number with 309 digits (more than 179 thousand centillion). However, using Double for whole number calculations is error-prone. Double is internally stored with floating point logic; the larger the number, the less exact it becomes. For instance, you cannot exactly represent the number ten quadrillion (i.e., ten million billion):

let x = 1.0e+16
let y = x - 1.0
printf "%b" (x = y)
// Prints true! 

Through the introduction of System.Numerics.BigInteger, it is now possible for any .Net Framework language to exactly represent any whole number whatsoever. In the following example, we will use this type to implement a function that calculates a range of arbitrarily large prime numbers. We will design it as a static library method which can be called by any .Net 4.0 client application. The signature, seen from C#, should be as follows:

Desired Signature, as Seen From C#

using System.Collections.Generic;
using System.Numerics;

namespace MyCompany.MyProduct{
    public static class BigMath{
        public static IEnumerable<BigInteger> 
        PrimesBetween(BigInteger i, BigInteger j){
            // etc.

Implementation in F#

To implement the library method, proceed as follows:

  • (If not done yet: Install the F# Power Pack)
  • Create a new F# class library project
  • Set the .Net Framework 4 client profile as the compilation target
  • Add references to System.Numerics.dll and FSharp.PowerPack.dll
  • Add a new source file BigMath.fs with the following code:
/// Provides static methods for mathematical functions involving 
/// arbitrarily large numbers. 
module MyCompany.MyProduct.BigMath

/// <summary>Gets a lazily evaluated sequence of prime numbers.</summary>
/// <param name="i">The beginning of the interval for the prime numbers.</param>
/// <param name="j">The end of the interval for the prime numbers.</param>
/// <returns>
/// A sequence with the prime numbers between <paramref name="i"/> 
/// and <paramref name="j"/>.
/// </returns>
let PrimesBetween(i, j) =
    /// Approximates the square root of a BigInteger with a 
    /// BigRational, according to the "babylonian method". 
    let sqrtI i =
        let iN = BigRational.FromBigInt i
        let half n = n / 2N
        let rec approachWith n =
            let diff = BigRational.PowN(n, 2) - iN
            if diff >= 0N && diff < 1N then n
            else approachWith(half(n + iN / n))
        approachWith(half iN)

    /// Gets true if i can be divided by a number >= 2,
    /// where i is a non-negative BigInteger.
    let hasDivisor i =
        let maxDiv = 
            let sr = sqrtI i
            min (sr.Numerator / sr.Denominator + 1I) (i - 1I)
        let rec hasDiv div =
            if div > maxDiv then false
            elif i % div = 0I then true
            else hasDiv(div + 1I)
        hasDiv 2I   

    /// Gets true if i is a prime number. 
    let isPrime i =
        match i with
        | _ when i < 2I -> false
        | _ when i = 2I -> true
        | _ -> not (hasDivisor i)

    /// The sequence of numbers between i and j.
    let range =
        let step = i |> compare j
        match step with
        | 0 -> Seq.singleton i
        | _ -> seq {i .. bigint step .. j}

    /// The resulting sequence of prime numbers between i and j.
    range |> Seq.filter isPrime  

Usage from C#

The compiled F# library can be used from C# as follows:

// using System;
// using MyCompany.MyProduct;
var primes = BigMath.PrimesBetween(10000200, 10000150);
foreach (var p in primes)
    Console.WriteLine(p.ToString("#,#"));
// Produces:
// 10,000,189
// 10,000,169

Concluding Remarks

The parameters of the PrimesBetween function are declared in tupled (not curried) form, which corresponds to par. 4.2 "Object and Member Design" of the F# Component Design Guidelines, which says "Do not use currying of parameters in vanilla .NET APIs".

All recursive functions are implemented tail recursively, using accumulator arguments, so that no stack overflow will ever occur.

The result is a strongly typed generic enumerable of BigInteger. At any given time, no more than one prime number is held in memory, regardless of the size of the interval between i and j.

The square root calculation in the sqrtI function is an optimization. To know whether a number has a divisor, it is sufficient to try division by all numbers between 2 and the square root. For the calculation of the square root, we use the type Microsoft.FSharp.Math.BigRational from FSharp.PowerPack.dll.

To calculate extremely large prime numbers in a productive situation, we would have to speed up the function using a cache. Perhaps unexpectedly, this cache would not necessarily store the resulting prime numbers. Instead, it would be gradually built with all prime numbers from the bottom up, starting at 2, whenever the recursive hasDiv function is called. The hasDiv function would then be modified to no more try out all whole numbers starting from 2 as potential divisors, but only all (recursively cached) primary numbers starting from 2, which is sufficient. This would enormously reduce the amount of divisions. The next step would then be to persist the cache in a database. The resulting library could be run for many years, returning larger and larger prime numbers, until (presumably) the currently calculated BigInteger number would be so large as to overstrain the system memory. I leave it up to you to speculate approximately when this might happen...

Declaring class constructors in F# 2.0, also considering singletons

by Marc Sigrist 19. October 2010 23:53

In F#, class constructors can be declared in several different ways. To declare a non-static class, one usually defines a primary constructor, plus zero or more additional constructors. To declare a static class, one usually defines a module.

Using a Primary Constructor

In F#, it is possible to create a thread-safe singleton with just three lines of code:

/// A public thread-safe singleton class in F#,
/// using a private primary constructor.
type Singleton private() =
    static let instance = Singleton()
    static member Instance = instance
// This would be the equivalent code in C#:
public class Singleton{ 
    static readonly Singleton instance = new Singleton(); 
    Singleton() {} 
    public static Singleton Instance {get { return instance;}} 
}

In the above F# example, private() defines an empty primary constructor. Using a primary constructor is the recommended practice for non-static classes in F#. According to the F# 2.0 Language Specification, section 8.6.4., any additional constructors must call the primary constructor (either directly or indirectly), as in the following example:

Using a Primary Constructor and an Additional Constructor

/// A public Person class in F#,
/// using a public primary constructor
/// and an additional public constructor.
type Person(name: string, guid) =
    new(name, guid) = Person(name, Guid.Parse(guid))
    member x.Guid = guid
    member x.Name = name
// This would be the equivalent code in C#:
public class Person{
     readonly string name;
     readonly Guid guid;
 
     public Person(string name, Guid guid){
          this.name = name;
          this.guid = guid;
     }
 
     public Person(string name, string guid):
          this(name, Guid.Parse(guid)){
     }
 
     public Guid Guid {get {return guid;}}
     public string Name {get {return name;}}
}

Using Only "Additional" Constructors

It is also possible to define classes in F# with only "additional" constructors, but no primary constructor. However, the available syntax for the rest of the class is quite restricted. Primary constructors should only be avoided when there is a very compelling reason to do so, e.g., to simplify automatic code generation. The following, modified Singleton example shows some of the difficulties you may face when avoiding a primary constructor:

/// This type is intended for private use within Singleton2 only.
type private SyncRoot = private new() = {}
 
/// A singleton with no primary constructor.
type Singleton2 =
     // As we cannot use implicit ("let"-bound) fields, we have to
     // use explicit ("val"-bound) fields. However, explicit fields
     // who are static must also be default-initialized, mutable, and private.
     [<DefaultValue>]
     static val mutable private instance: Singleton2
 
     private new() = {}
 
     // As we cannot rely on the inherent thread safety of non-mutable
     // let-bound fields, we have to apply a lock.
static member Instance = lock typeof<SyncRoot> (fun() -> if Unchecked.compare Singleton2.instance Unchecked.defaultof<Singleton2> = 0
then Singleton2.instance <- Singleton2()) Singleton2.instance

Using no Constructor at all

What happens if you define a class in F# without using any constructors at all? As opposed to C#, F# will not generate a default public parameterless instance constructor for you in the background. Your F# class simply cannot be instantiated. Oddly enough, while the compiler forbids the declaration of static fields via let bindings in this scenario (whose usage would seem to make sense), it does not complain if you define instance properties/methods/val bindings (who are useless, because they can never be accessed). This leaves you with only static properties/methods/val fields, which is quite restrictive. Furthermore, even if you decide to define such a "type with only static accessibility", it will not appear as a "static class" to its users. For these reasons, it is best to never define classes without constructors in F#. If you need what in C# we call a static class, you better define a module in F#:

Declaring a Static Class

/// A module (static class) defined in F#. Type-level let bindings are public by default,
/// but can also be internal or private. This is opposed to type (non-static class)
/// definitions, where type-level let bindings are always inherently private.
module PersonFactory =
     let CreatePerson(name, guid: Guid) = new (name, guid)
// This would be the equivalent code in C#:
public static class PersonFactory{
     public static Person CreatePerson(string name, Guid guid){
         return new Person(name, guid);
     }
}

However, using modules in F# 2.0 has a certain disadvantage: Method overloading is not possible. If you need method overloading in a static class, there is no other way than declaring a non-static type with just a private parameterless constructor, or no constructor at all:

/// A class with overloaded members in F#.
type PersonFactory2 =
     static member CreatePerson(name, guid: Guid) = Person(name, guid)
     static member CreatePerson(name, guid: string) = Person(name, guid)
// This would be the equivalent code in C#:
public class PersonFactory2{
     public static Person CreatePerson(string name, Guid guid){
          return new Person(name, guid);
     }
 
     public static Person CreatePerson(string name, string guid){
          return new Person(name, guid);
     }
}

No Static Constructor Method in F#

There is no separate static constructor method in F#. In order to run "static constructor code" in F#, you first need to declare a primary constructor. A primary constructor is actually an instance constructor (it can have a non-public access modifier and can take arguments). However, if and only if a primary constructor exists, any type-level static let and do-bound code implicitly becomes "static constructor code".

/// Running "static constructor code" in F#.
type SomeType() =
     static let instanceCount = ref 0
     static do printfn "Type created at %A" DateTime.Now
     do printfn "Instance created at %A" DateTime.Now
     do incr instanceCount
     static member InstanceCount = !instanceCount
// This would be comparable code in C#:
public class SomeType{
     static SomeType(){
         Console.WriteLine(
              string.Format("Type created at {0:G}", DateTime.Now));
     }
 
     public SomeType(){
         Console.WriteLine(
              string.Format("Instance created at {0:G}", DateTime.Now));
         InstanceCount++;
     }
 
     public static int InstanceCount {get; private set;}
}

In this blog post, I have covered the basics of declaring F# constructor code for class types and modules. Much more could be said with regards to type construction in F#. For instance, I did not cover structures, records, object expressions, calling base class constructors, and the details of read-only fields versus mutable fields versus reference value fields. Further information can be found in the F# specification, F# Language Reference, F# documentation, or in one of the few outstanding books available, such as Programming F#.

Tags: , ,

F#

Book review: Programming F#

by Marc Sigrist 12. April 2010 00:33
Programming F# Title: Programming F#
Subtitle: A comprehensive guide for writing simple code to solve complex problems
Publisher: O'Reilly®
Author: Chris Smith
Date of appearance: October, 2009 (416 Pages)

The new version of Visual Studio is officially released today, April 12, 2010. It contains a new language called „F#“, designed by Don Syme of Microsoft Research Cambridge, UK. F# is a programming language that has capacities comparable to C#, but also offers the possibilities of a functional language. It is therefore a multiparadigm language; instead of “F#”, I think it could also have been called "M#".

Before discussing the book, let me mention how I came from C# to F#. I seriously started investigating F# after having written, maybe for the the 10,000th time or so, something like:

/// ...
/// <exception cref=“ArgumentNullException“>
/// <paramref name=“bar“> is <see langword=“null“>.
/// </exception>

void Foo(Bar bar) {if (bar == null) throw new ArgumentNullException("bar");}

Even if one uses helper methods, code snippets, or (in .NET 4.0) a preconditional code contract, writing the non-null enforcement logic still remains an annoyingly repetitive task. One day, I read in a blog comment: "If you want a language with reference types that cannot be null, take a look at F#". This sounded like Christmas to me. After some further research, I decided to take the time to learn this new language.

The book appeared only recently and is up-to-date with the current F# 2.0 release. It was written by Chris Smith, Software Design Engineer in Test at the F# team. It contains a densely written overview of the complete F# language. The writing follows a systematic path from the simple to the advanced. There is always a short introduction of a feature, followed by an extensive example, followed by further comments.

In the introductory chapter, we learn that white space matters: In order to create hierarchies of scope in code, one simply uses new lines and indentations, not curly braces and semicolons. Functions can easily be nested in other functions, which can be nested again in still other functions ad infinitum. Each subordinated function has its own narrow scope, which eliminates an important source of bad programming design. Oftentimes, parameter types do not have to be declared, because the compiler can infer them automatically. If so, one can also avoid writing parentheses () for the parameters. Taken together, these features make the F# language nicely self-documentary. Even without looking at the details, from the tense, clear-cut, indented shape of the code alone, one can quickly get a sense of the logical structure.

Conceptually, you could do the same already in C# 2.0 by nesting anonymous methods within each other. However, even in C# 3.0/4.0, nesting lambdas, the code soon becomes convoluted. As a consequence, in C#, one tends to implement functions without applying the appropriate level of local nesting, or even to declare private methods where anonymous methods would be more logical, thereby violating scope. Declaring private types nested in other private types is not really an alternative, because the declaration has to be outside the method, and it all takes so many lines of code that the whole construct will finally diffuse its own purpose to the reader. The way I see it, by offering the feature of function nesting, functional languages promote the object-oriented principle of encapsulation in a more sophisticated and fine-grained way than object-oriented languages themselves.

As one continues reading the first three chapters, the thinking adapts more and more to the fact that functions are just like other values. F# allows you (through partial function application) to transform functions into other functions with less parameters, and (through "currying" with pipes) to build chains of functions in a natural, intuitive way. Discriminated unions are another productivity-enhancing feature: Imagine enums in C#, but with nearly unlimited freedom in defining (and nesting, and sub nesting...) each enum member. Discriminated union members can be matched to other values via typed pattern matching, another fascinating feature, something like C# switch statements on steroids. Together, discriminated unions and pattern matching save many lines of code and of potential errors. They also make the code spontaneously conceivable-at-a-glance, without having to go back and forth through page after page in the code editor to understand the mapping logic.

Another interesting aspect of F# is the built-in special support of collection-like types. F# tuples internally rely on the .NET 4.0 Tuple type (an ordered collection of differently typed, nameless values). F# records are like C# 3.0 anonymous types, without the anonymity (a collection of differently typed, named values). F# lists are read-only singly linked lists of equal types. Of course, F# also has built-in support for arrays and sequences. The language contains specific operators and other constructs to make the declaration, initialization, and general handling of collection-like types as intuitive and natural as possible, allowing you to "write the code the way you think" and let the compiler do the work of implementing your expressed intentions. It is also possible to use the generic collections from the .NET Framework.

Chapter 4 deals with imperative programming in F#, i.e., programming that alters data that is already in memory. This subject is presented in its own separate chapter, because, by default, F# values can never be null and can never be mutated, even if they are of reference types. The chapter explains how you can digress from the default behavior, including how to deal with .NET Framework members that request or may return null.

Chapter 5 explains object-oriented programming in F#. The author starts with a brief explanation of what object orientation is and why it is useful. These remarks are probably directed at proponents of so-called "pure" functional languages (such as Haskell), who might be skeptical about, or not accustomed to, object orientation. However, the author also mentions some shortcomings of pure object orientation. Among other things, it forces the developer to formally implement certain design patterns, which, in functional languages, are implicitly there without needing special consideration.

Chapter 6 shows how to do classical .NET programming with F#, with some exciting extensions. For example, in F#, using object expressions, it is possible to create an "inline instance" of an interface type, without declaring a named, implementing type first. The chapter also explains how to declare and use standard .NET enumerations (instead of F# discriminated unions) and compares F# value types with F# records.

Chapter 7 deals with applied functional programming. It introduces units of measure and explains the usage of active patterns. Active patterns allow using functions inside the pattern matching. The author points out the three kinds of active patterns: Single-case, partial-case, and multi-case, and how they can be nested. The chapter also shows how to use F# lists in recursions. I was amazed by the fact that the F# compiler automatically generates code that avoids a stack overflow when the recursion is implemented in the “tail-recursive” style. A variation of this is the “continuation passing style”, which prevents stack overflows even when two interdependent recursive functions are involved. The chapter goes on with examples with function currying and the forward pipe operator (for a list of F# operators, see here), followed by closures, memoizing, and lazy evaluation, which should be familiar to C# programmers.

Chapter 8 is about applied object-oriented programming in F#. Any arbitrary symbol may be defined as an operator. One can declare indexers, and also “slices”, which return a sub range of a collection via slice notation. In addition to the generic type constraints known from C#, F# offers type constraints for delegate, enumeration, comparison, and equality conditions. As far as events are concerned, using the F# Observable module, one can define, compose, transform, merge, and map events in various ways. Chapter 9 demonstrates how to use F# as a scripting language. Even in scripted usage, F# is always compiled first, and therefore is faster than regular scripting languages. The chapter also contains a few pages about Microsoft Office automation with F#.

Chapters 10 to 13 contain more advanced F# concepts, which, coming from a C# background, were something like a revelation to me. Using computation expression builders, one can redefine the behavior of keywords such as while, return, yield, try/finally, etc., to create custom background processing for asynchronous workflows. F# allows you to call asynchronous operations almost like synchronous ones. You do not need to apply the traditional Asynchronous Programming Model (APM) of the .NET Framework, which is not type safe, and depends on separate callback methods spread in the class. Fortunately, version 4.0 of the .NET Framework contains Parallel Extensions for .NET (PFX) and thread-safe concurrent collections, with some further optimizations, ready to be used by any .NET language. Chapter 12 deals with reflection and declarative programming in F#. Using F# code quotations, one can access not only the static type information (as in classical reflection), but also the compiler’s internally used abstract syntax tree (AST). This is conceptually similar to, but much more elaborate than, expression trees known from lambdas in C# 3.0.

I would like to recommend this book to experienced developers seriously interested in F#. Readers without a functional background had better not expect to understand everything immediately upon a superficial first reading. The content is quite condensed, and many concepts are new to object-oriented developers. However, once you open yourself up to new ways of thinking about code, chances are you will become truly enthusiastic about the power and intuitiveness of this elegant new language. 

Prerequisits for implementing a keep-alive mechanism in WCF 3.0

by Marc Sigrist 7. March 2010 00:59

There seems to be a common misconception that, in order to find out whether a WCF session is still alive, one has to implement some kind of custom ping or heartbeat operation on the service, which is to be regularly called by the client application. However, the WCF framework, when configured correctly, already does this for you in the background.

The key to this feature is the ReliableSession class. When ReliableSession.Enabled is true, WCF will continuously generate internal infrastructure messages to check whether the service is still ready. After the service has been dead for some specified time, the proxy's ClientBase<TChannel>.State is automatically set to CommunicationState.Faulted, and the ICommunicationObject.Faulted event is raised, giving the client application a chance to react. The delay between the service breakdown and the Faulted event can be specified through the ReliableSession.InactivityTimeout. If, for instance, the InactivityTimeout is set to four minutes, WCF will generate several infrastructure messages during every four minutes. Therefore, if you shut down the service, the Faulted event will be raised on the client after four to six minutes. If you set the InactivityTimeout to 20 seconds, it will be raised after 20 to 30 seconds. The exact duration depends on WCF-internal implementation details.

In order for this to work, you also have to set the Binding.ReceiveTimeout to at least the duration of the InactivityTimeout. The ReceiveTimeout specifies how long the service will stay alive without any service operations being called from the client application. If, for instance, you expect your client application to call service operations at least twice an hour, you may set the ReceiveTimeout to 30 minutes, but still let the InactivityTimeout be 4 minutes or so, in order that the client application can take measures in the background when the service is temporarily interrupted.

The following example shows how to define both timeouts on the client and server sides, either configuratively (in the App.config file) or imperatively (in code). The example presupposes that you are using a reliable session-capable binding (such as WSHttpBinding or NetTcpBinding), and that you have applied the ServiceContractAttribute.SessionMode, ServiceBehaviorAttribute.InstanceContextMode, OperationContractAttribute.IsInitiating, and OperationContractAttribute.IsTerminating properties in meaningful ways. If you are not sure about that, you may want to read the respective MSDN documentation entries first. A comparison table of the system-provided bindings can be found here. Furthermore, if you do not like hand-coding configuration files, you can use the WCF service Configuration Editor Tool, which is installed with the Microsoft Windows SDK.

Defining the Timeouts Configuratively

<configuration>
  <
system.serviceModel>

    <!--
In the App.config files of the service host and client apps: -->
    <
bindings>
      <
netTcpBinding>
        <
binding name="myNetTcpBinding" receiveTimeout="00:30:00">
          <
reliableSession enabled="true" inactivityTimeout="00:04:00"/>
        </
binding>
      </
netTcpBinding>
    </
bindings>

    <!--
In the App.Config file of the service host app: -->
    <
services>
      <
service name="MyTest.MyService">
        <
endpoint
        
address="net.tcp://localhost/MyService/"
        
binding="netTcpBinding"
        
bindingConfiguration="myNetTcpBinding"
        
contract="MyTest.IMyService"/>
      </
service>
    </
services>

    <!--
In the App.Config file of the client app: -->
    <
client>
      <
endpoint
      
address="net.tcp://localhost/MyService/"
      
binding="netTcpBinding"
      
bindingConfiguration="myNetTcpBinding"
      
contract="MyTest.IMyService"/>
    </
client>

  </
system.serviceModel>
</
configuration>

Defining the Timeouts Imperatively

// using System;
// using System.ServiceModel;

// In the service host and client apps:

var
myNetTcpBinding = new NetTcpBinding();
myNetTcpBinding.ReceiveTimeout = new TimeSpan(0, 30, 0);
myNetTcpBinding.ReliableSession.Enabled = true;
myNetTcpBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 4, 0);

// In the service host app:
var
host = new ServiceHost(typeof(MyService));
host.AddServiceEndpoint(typeof(IMyService), myNetTcpBinding, "net.tcp://localhost/MyService");

// In the client app:
var
factory = new ChannelFactory<IMyService>(myNetTcpBinding, "net.tcp://localhost/MyService");
var 
channel = factory.CreateChannel();

Book review: Pro WPF in C# 2008

by Marc Sigrist 27. February 2010 17:55
Book image Title: Pro WPF in C# 2008
Subtitle: Windows Presentation Foundation with .NET 3.5, Second Edition
Publisher: Apress® Books for Professionals by Professionals™
Series: The Expert's Voice in .NET
Author: Matthew MacDonald
Date of appearance: February, 2008 (1040 Pages)

This book is a thorough examination of the WPF 3.5 technology – its architecture, what you can do with it, and how to do it. It is directed at professional C# developers.

The book is written in a systematic, comprehensible way. A chapter starts with a basic introduction and includes graphics of the respective WPF sub-class hierarchy. The chapter's subject is then steadily explored in more and more detail. For instance, at the beginning, there are five pages just on resolution independence. XAML is explained in-depth, starting with the four ways of loading and compiling: Code-only, code and uncompiled XAML, code and compiled XAML, and XAML only; this is followed by the specifics of the XAML grammar (markup extensions, attached properties, etc.). There are seven pages on non-rectangular windows and sixteen pages on playing sound on different OS versions. As the book goes on, the author really shines in describing complex subjects, such as 3-D drawing, in a logically understandable way. Towards the end, there is a tabular overview of features missing in WPF compared to Windows Forms, with recommendations on when to choose one over the other, or both of them together, and how to mix them best.

The volume also contains lots of small, but precious pieces of surplus information, such as: Properties of WPF controls can be set in any order, without causing any change in behavior; or: By using an overloaded version of DependencyObject.SetValue in code, you can attach a value for any dependency property, even if it is not defined as an attached property (which is not possible in XAML). In addition, the author mentions various quirks of WPF, and how to get around them, if possible. Example: When you restart an animation that is almost complete, and the animation had the current position as the starting point, the animation will appear to slow down. Another example: Windows Vista always requires permission elevation for a setup, even though, in the case of Click Once, this makes no sense. As a consequence, a Click Once WPF application, on Vista, cannot be installed under a regular user account; the user is forced to install it under an admin account - which defeats the purpose of using Click Once in the first place...

Developers are all-too-familiar with the Pareto principle: 80% of the tasks of a project can be solved „easily“ in 20% of the time, but solving the other 20% takes at least 80% of the time. If you want to use WPF in a productive way, I strongly recommend taking the time to study this book. Admittedly, at 1040 pages, this is quite some endeavor. However, you will be rewarded many times over, as you will be saved a lot of frustration and unexpected delays, when you already know from the beginning how to solve much of the other 20%.

Yet another comment on the C# cast ( ) and „as“ operators…

by Marc Sigrist 21. February 2010 19:39

Time and again, the question comes up whether to prefer the cast ( ) or the „as“ operator in C# to perform conversions to reference types. According to the C# 3.0 language specification, the two operators behave differently in several respects:

C# Conversion Operator( )as
Name Cast operator as operator
C# 3.0 Specification section 7.6.6 7.9.11
Can convert to ValueType Yes No
Executes user-defined explicit conversions Yes No
Compile-time errors CS0030: Cannot convert type 'X' to 'Y'. CS0030: Cannot convert type 'X' to 'Y'.
CS0077: The as operator must be used with a reference type or nullable type ('Y' is a non-nullable value type).
Runtime behavior if not convertible Throws InvalidCastException: "Unable to cast object of type 'X' to type 'Y'." Returns null

Given the above comparison table, it follows that you must use the cast operator ( ) in the following cases:

  • to convert to a ValueType:
    object o = 137; var i = (int)o;
  • to convert via a user-defined explicit operator overload defined in the source type. Note that the overload may return anything whatsoever: The same instance, a new instance of the same type, a new instance of a completely non-related type, null, a value type or reference type...
    // Declared inside a class called Source:
    static explicit operator Target(Source s) {return new Target();}

By contrast, you must use the "as" operator in the following cases:

  • to be 100% sure that that the result points to the same instance, or null, but never anything else:
    var bar = foo as Bar;
  • to return null if a runtime conversion to the desired reference type is not possible, as in this construct:
    var bar = foo as Bar ?? new Bar();

Furthermore, the "as" operator is a bit more tolerant with generics at compile time than the cast operator. That’s because the as operator casts „directly“ to a type of the same inheritance line:

TDerived GetDerived<TBase, TDerived>(TBase b) where TDerived: class {
    // Produces compiler error CS0030: Cannot convert
    // type 'TBase' to 'TDerived'.

    // return (TDerived)b;

    // This compiles...
    return
b as TDerived;
}

In all other cases, from a technical point of view, you may freely choose between the cast and the "as" operator. Therefore, the „right“ decision depends on what you want to express most in the source code. If you use the "as" operator, you thereby clearly document that you are interested in a reference target type that points to the same instance, and nothing else whatsoever – i.e., you do not want some crazy custom explicit operator to produce any side effects! Moreover, as a matter of taste, the "as" operator makes your code less cryptic, because it uses no parentheses, whereas the cast ( ) operator looks like old-fashioned C code.

For these reasons, personally, I prefer the "as" operator over the cast ( ) operator. However, I have met other developers who almost religiously defend usage of the cast ( ) operator as a best practice, „because it immediately throws an InvalidCastException“ at runtime if necessary, while the "as" operator might only later produce a NullReferenceException. Yet, against this, it could be argued that the "as" operator is even more secure, because it does not allow you to compile if it’s a value type, and it will never produce side effects...

Some tools, such as JetBrains‘ ReSharper, warn you if you apply the "as" operator without checking for null with a null comparison within the same procedure, even if null is logically impossible; e.g., when you have defined a null-checking procedure in a separate external helper method. You can turn this off, but only on a per-user basis. Others who look at your code may still see the warning. You may also disable the warning by surrounding the „critical“ section with a specific ReSharper comment, but it’s annoying to have your code cluttered like this. Therefore, if your company uses ReSharper, this might be a pragmatic reason to prefer the cast ( ) operator over the "as" operator.

In my opinion, it would be better if the C# "as" operator did not return null, but throw an InvalidCastException if the direct cast is not possible. Nothing of importance would be lost by this – you can always check for null with the "is" operator - but a lot of misunderstandings and disagreements would be prevented. Interestingly, the VB.NET language has the DirectCast operator, which does exactly this. A similar behavior could be implemented in C# like this:

public static T As<T>(this object o) where T: class{
    if
(o == null) throw new NullReferenceException();
    if
(!(o is T)) throw new InvalidCastException();
    return
o as T;
}