F# Weekly #15, 2013

Weekly15
Don Syme talks Big Data and F# for Big Data Hackaton

Welcome to F# Weekly,

A roundup of F# content from this past week:

News

Blogs

Pingback to the past:

That’s all for now.  Have a great week.

Previous F# Weekly edition – #14

Running F# Interactive from Windows context menu

It is looks like really reasonable option!

Gene Belitski's avatarIn F# Major

Today a question popped up on Stack Overflow on how to arrange running F# scripts from Windows context menu, but in case of abnormal termination still having opportunity to access diagnostics. Regular context menu item Run with F# interactive lacks the latter because interactive console window closes abruptly on script failure.

Although I gave an outline of the solution as Stack Overflow answer, it lacks level of details that those who want to use such feature may find useful. So, I decided to give here a more detailed description. I will show the implementation for my own work environment, which is Windows 7 Ultra x64 + VS2012 Ultra RC. Reproducing the approach for other environments may require trivial adjustments.

1. Let’s begin with spying the mechanics of stock context menu item Run with F# interactive… implementation. Let’s fire regedit in Run as Administrator mode and search through the registry for…

View original post 209 more words

F# null trick

fsharp_null_250I have faced with an interesting F# behaviour on the null check. I tried to make a MongoDB query using C# Driver LINQ but F# compiler said that I could not compare the result with null, because result could not be null, but I am sure that query can return nothing =).

I am going to show you the same behaviour with classic LINQ. Please, look at the source code:

open System
open System.Linq
open System.Collections.Generic

type typeA = {Variable:int}

let x = List<typeA>().FirstOrDefault()

if (x = null) then None else Some(x)

If you evaluate first 7 lines of code, you will see that x is equal to null, List is empty, so the value of our LINQ query will be default(null). But, if you try to execute the line number 9, F# compiler will say that it cannot be compiled, because the typeA does not have a null as a proper value, but x is null! Hmm… real magic…

null_trick.fsx(9,9): error FS0043: The type ‘typeA’ does not have ‘null’ as a proper value

Actually, there is an excellent MSDN article “Null Values (F#)“, which should be read carefully. At the first look you may think that AllowNullLiteralAttribute is an answer and try to modify the typeA in the following way:

[<AllowNullLiteral>]
type typeA = {Variable:int}

But you can not have this code compiled, because

null_trick.fsx(6,6): error FS0934: Records, union, abbreviations and struct types cannot have the ‘AllowNullLiteral’ attribute

CLIMutableAttrubute is not an option too, because it does not affect null-behaviour. At the end of the “Null Values (F#)” article you will see an interesting example with a null check:

match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."

Boxing is an answer! We need it to perform a null check for an arbitrary value. So, the working example will look like:

open System
open System.Linq
open System.Collections.Generic

type typeA = {Variable:int}

let x = List<typeA>().FirstOrDefault()

if (box x = null) then None else Some(x)

F# world is full of magic. Wonders await us at every turn.

P.S. Read more tales of null in Steffen Forkmann’s blog.

F# Exception Formatter

200px-exception-printerDetailed pretty printed exception is a key to understand the real cause of the problem. We have a piece of code in C# that was reused for many projects, which formats exceptions sequence into human readable form with all exception details.

This source code was translated from C# and hopefully will be helpful to someone else:

open System
open System.Reflection
open System.Text
open Microsoft.FSharp.Core.Printf

let formatDisplayMessage (e:Exception) =
    let sb = StringBuilder()
    let delimeter = String.replicate 50 "*"
    let nl = Environment.NewLine
    let rec printException (e:Exception) count =
        if (e 😕 TargetException && e.InnerException <> null)
        then printException (e.InnerException) count
        else
            if (count = 1) then bprintf sb "%s%s%s" e.Message nl delimeter
            else bprintf sb "%s%s%d)%s%s%s" nl nl count e.Message nl delimeter
            bprintf sb "%sType: %s" nl (e.GetType().FullName)
            // Loop through the public properties of the exception object
            // and record their values.
            e.GetType().GetProperties()
            |> Array.iter (fun p ->
                // Do not log information for the InnerException or StackTrace.
                // This information is captured later in the process.
                if (p.Name <> "InnerException" && p.Name <> "StackTrace" &&
                    p.Name <> "Message" && p.Name <> "Data") then
                    try
                        let value = p.GetValue(e, null)
                        if (value <> null)
                        then bprintf sb "%s%s: %s" nl p.Name (value.ToString())
                    with
                    | e2 -> bprintf sb "%s%s: %s" nl p.Name e2.Message
            )
            if (e.StackTrace <> null) then
                bprintf sb "%s%sStackTrace%s%s%s" nl nl nl delimeter nl
                bprintf sb "%s%s" nl e.StackTrace
            if (e.InnerException <> null)
            then printException e.InnerException (count+1)
    printException e 1
    sb.ToString()

Now, you can print exceptions into a more readable form. For example, if you execute this expression:

let x =
    try
        try
            Some(10 / 0)
        with
        | e -> InvalidOperationException("Incorrect operation",e) |> raise
    with
    | e ->
         printfn "%s" (e|>formatDisplayMessage)
         None

you will see the following output

Incorrect operation
**************************************************
Type: System.InvalidOperationException
TargetSite: Void main@()
Source: FSI-ASSEMBLY
HResult: -2146233079

StackTrace
**************************************************

at <StartupCode$FSI_0019>.$FSI_0019.main@() in D:\Projects\Exception.fs:line 48

2)Attempted to divide by zero.
**************************************************
Type: System.DivideByZeroException
TargetSite: Void main@()
Source: FSI-ASSEMBLY
HResult: -2147352558

StackTrace
**************************************************

at <StartupCode$FSI_0019>.$FSI_0019.main@() in D:\Projects\Exception.fs:line 46

P.S. If you wish, you can add this function into FSI printers list.

fsi.AddPrinter(formatDisplayMessage)

F# Weekly #14, 2013

fsharp_girlWelcome to F# Weekly,

A roundup of F# content from this past week:

News

Video

Blogs

That’s all for now.  Have a great week.

Previous F# Weekly edition – #13

F# Weekly #13, 2013

censoredWelcome to F# Weekly,

One more week has passed. This past week was full of interesting blog posts that are waiting for you:

News

Video

Blogs

That’s all for now.  Have a great week.

Previous F# Weekly edition – #12

“Probably the best coffee in the world.” by Dave Thomas