Personally I have been sold on F# for a long time but some people however will need a lot of convincing before they move out of their comfort zone. Hopefully after reading this you will be more inclined to try it out.

Imagine you were given a directory full of files that did not have any file extensions and were told to figure out the file extension for every file. Picture how you might do this in VB or C#. Now take a look at this:

OCaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(*
Notice how we don't need to specify the type for filePaths?
The compiler will infer the type based off how we use the parameter.
When we call File.OpenRead the compiler will know that filePaths has to be a
string seq or IEnumerable<string> in C# speak.
*)
let getUnknownFileExtensions filePaths =
    filePaths
    |> Seq.map(
        fun filePath ->
            use fs = System.IO.File.OpenRead(filePath)
            let buffer = Array.zeroCreate 8
            let read = fs.Read(buffer, 0, 8)
            match buffer with
            (*The underscore tells the compiler that we dont care what the byte is at that index.*)
            | [| 0xFFuy; 0xD8uy; _; _; _; _; _; _; |] -> 
                (filePath, ".jpg")
            | [| 0x25uy; 0x50uy; 0x44uy; 0x46uy; _; _; _; _; |] -> 
                (filePath, ".pdf")
            | [| 0x50uy; 0x4Buy; 0x03uy; 0x04uy; _; _; _; _; |] -> 
                (filePath, ".docx")
            | [| 0xD0uy; 0xCFuy; 0x11uy; 0xE0uy; 0xA1uy; 0xB1uy; 0x1Auy; 0xE1uy; |] -> 
                (filePath, ".doc") 
            | _ -> 
                (filePath, ".unk")
    )
    |> Seq.iter(
        fun (filePath, extension) ->
            System.IO.File.Move(filePath, filePath + extension)
    )
(*
Notice how we don't need to specify the type for filePaths?
The compiler will infer the type based off how we use the parameter.
When we call File.OpenRead the compiler will know that filePaths has to be a
string seq or IEnumerable<string> in C# speak.
*)
let getUnknownFileExtensions filePaths =
    filePaths
    |> Seq.map(
        fun filePath ->
            use fs = System.IO.File.OpenRead(filePath)
            let buffer = Array.zeroCreate 8
            let read = fs.Read(buffer, 0, 8)
            match buffer with
            (*The underscore tells the compiler that we dont care what the byte is at that index.*)
            | [| 0xFFuy; 0xD8uy; _; _; _; _; _; _; |] -> 
                (filePath, ".jpg")
            | [| 0x25uy; 0x50uy; 0x44uy; 0x46uy; _; _; _; _; |] -> 
                (filePath, ".pdf")
            | [| 0x50uy; 0x4Buy; 0x03uy; 0x04uy; _; _; _; _; |] -> 
                (filePath, ".docx")
            | [| 0xD0uy; 0xCFuy; 0x11uy; 0xE0uy; 0xA1uy; 0xB1uy; 0x1Auy; 0xE1uy; |] -> 
                (filePath, ".doc") 
            | _ -> 
                (filePath, ".unk")
    )
    |> Seq.iter(
        fun (filePath, extension) ->
            System.IO.File.Move(filePath, filePath + extension)
    )

Now that is what I call productive programming!