F# Weekly #4, 2014

I love F#

Welcome to F# Weekly,

A roundup of F# content from this past week:

News

Video/Presentations

Blogs

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

Previous F# Weekly edition – #3

Subscribe

F# Weekly #3, 2014

Welcome to F# Weekly,

A roundup of F# content from this past week:

News

Video/Presentations

Blogs

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

Previous F# Weekly edition – #2

Subscribe

Building an “actor” in F# with higher throughput than Akka and Erlang actors

Amazing post!!!

Zach Bray's blog

Building an “actor” in F# with higher throughput than Akka and Erlang actors

The “Big Data” problem

Our free lunch is over!

The number of transistors in our CPUs is still increasing like Moore’s law predicted. However, the frequency of our chips is flat-lining. We can no longer expect to see a 2x or even 1.5x performance improvement every 18 months from code that doesn’t exploit parallelism.

“Big Data” has arrived

According to Cisco we are now in The Zetabyte Era.

Global IP traffic has increased eightfold over the past 5 years.

Globally, mobile data traffic will increase 18-fold between 2011 and 2016.

The Economist ran an article in 2010 on what some are calling “the industrial revolution of data”.

Oracle, IBM, Microsoft and SAP between them have spent more than $15 billion on buying software firms specialising in data management and analytics.

This industry is estimated to…

View original post 2,148 more words

F# Kung Fu #3: Exceptions recap.

Define

Usually, you do not need to define custom exceptions during programming in F#. If you do scripting in F#, in the most cases you will be happy with standard .NET exception types and F# built-in helper functions. But when you create a custom library or design complex enterprise software, you will need to use power of .NET exceptions. How you can do it from F#:

// C# style exception (possible, but not recommended)
type MyCsharpException(msg, id:int) =
  inherit System.Exception(msg)
  member this.Id = id

// F# style exceptions
exception MyFsharpSimpleException
exception MyFsharpException of string * int

Note that F# has a special keyword exception for defining “handy” exceptions.

Raise(Throw)

F# provides set of functions (failwith, failwithf, invalidArg, invalidOp, nullArg) that help to raise most common exceptions. They are very convenient especially for F# scripts.

let rnd = System.Random()

let rnd = System.Random()

let raiseException() =
    match rnd.Next(8) with
    | 0 -> failwith "throws a generic System.Exception"
    | 1 -> failwithf "throws a generic Exception with formatted message (%d)" 1
    | 2 -> invalidArg "_" "throws an ArgumentException"
    | 3 -> invalidOp "throws an InvalidOperationException"
    | 4 -> nullArg "throws a NullArgumentException"
    | 5 -> raise <| MyFsharpException("throws a MyFsharpException", 5)
    | 6 -> raise <| MyCsharpException("throws a MyCsharpException", 6)
    | 7 -> assert (2>1)
    | _ -> raise <| System.Exception("Impossible case")

The assert expression is syntactic sugar for System.Diagnostics.Debug.Assert. The assertion is triggered only if the DEBUG compilation symbol is defined.

Try-With/Finally (Catch)

The last step is to catch exceptions and handle them in a proper way.

let catchException() =
    try
        raiseException()
    with
    | Failure(msg) // 'Failure' active pattern catches only Exception objects
     -> printfn "%s" msg
    | MyFsharpException(msg, id)
     -> printfn "Catch F# exceptions using pattern matching"
    | : ? System.ArgumentException as ex
     -> printfn "Invalid argument '%s'" ex.ParamName
    | : ? MyCsharpException | : ? System.InvalidOperationException
     -> printfn "You can handle multiple exceptions at a time"
    | _ as ex
     -> printfn "Log: exception '%s'" (ex.GetType().Name)
        reraise() // re-raise exception

let finaly() =
    try
        catchException()
    finally
        printfn "Now, I am ready for exceptions!"

: ?‘ is a two-symbol operator without space inside.

Note:

  • Failure active pattern catches only System.Exception objects. It is useful to handle exceptions raised by failwith & failwithf functions.
  • Exceptions defined using exception keyword could be handled automatically using pattern matching.
  • F# provides reraise function that helps to raise a current exception one more time. This function can be used only from pattern matching rules of try-with expressions.

If you want to learn more about exceptions, read an amazing The “Expressions and syntax” series from Scott Wlaschin.

F# Weekly #2, 2014

Welcome to F# Weekly,

A roundup of F# content from this past week:

News

Blogs

FsAdventJP

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

Previous F# Weekly edition – #1

Subscribe

F# Kung Fu #2: Custom Numeric Literals.

All of you probably know that F# has a set of predefined numerical literals that allow you to clarify meaning of numbers. For example, number 32 will be interpreted as int by default. If you add ‘L’ suffix – 32L, you will get int64 number. If you add ‘I’ suffix- 32I, you will get System.Numerics.BigInteger number.

But F# has an extensible point here: you can define custom interpretation for suffixes Q, R, Z, I, N, G. The trick is that you need to declare an F# module with a special name and define converters functions. (For example NumericLiteralZ for Z literal).

module NumericLiteralZ =
    let FromZero() = 0
    let FromOne() = 1
    let FromInt32 n =
        let rec sumDigits n acc =
            if (n=0) then acc
            else sumDigits (n/10) (acc+n%10)
        sumDigits n 0
    //let FromInt64 n = ...
    //let FromString s = ...

let x = 11111Z
//val x : int = 5
let y = 123Z
//val y : int = 6

Have fun, but be careful.

Update: Note that you cannot use constants integer literals with suffixes Q, R, Z, I, N, G in pattern matching.

Subscribe to F# Weekly by Email

email-iconNew service announcement

From now you have an unique possibility to subscribe to F# Weekly by email. Do it if you would like to get a Friday newsletter with F# Community news from past week: https://tinyletter.com/sergey_tihon

Caution: All other resources that claim that they offer subscription to F# Weekly (like http://fsharpweekly.com/) are unofficial. They do not belong to me and I cannot guarantee safety of your email addresses.

F# Weekly #1, 2014

Welcome to F# Weekly,

A roundup of F# content from this past week:

News

Video/Presentations

Blogs

FsAdventJP

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

Previous F# Weekly edition – #52

NDepend for F# code or FSharp.Compiler.Service ‘code review’.

ndepend_logoI had the opportunity to play with NDepend and could not keep from trying it on F# code. It is interesting to see how analysis rules that designed for languages like C# apply to functional-first F#.

When I downloaded NDepend from the official site, I expected to get regular msi installer with wizard that passes me through all steps and does everything it needs. But it was not true, I got a zip archive with binaries that I needed to unzip manually and execute some binaries that integrate NDepend with my Visual Studio 2013 and Reflector. Installation guide is simple enough and detailed, I have no problems to follow it step by step and configure everything. Nevertheless, installation process seems rather unusual for today.

When I executed a standalone version of NDepend(VisualNDepend) and opened first project that I found – I got stuck! So much information on my screen, I could not understand where to look. My screen looked like a spaceship control panel and I was afraid to touch it ;). I decided to go back to Getting Started page and watch the introduction video. Luckily, NDepend looks pretty well documented.

Now I needed to choose some F# project to do “a code review”. I wanted to find something cool, large and complicated for clarity. And here was my first problem… The first condition is ‘cool’, but most of open source F# projects are cool. This constrain did not help me to reduce number of choices. The next condition is ‘large’, but we do not have really huge F# projects. Pithiness is one of the main F# advantages (F# helps to dramatically decrease code size and code complexity by design). Even F# Compiler is not so big; it is much smaller than my usual C# project. The last condition is ‘complexity’; here situation is similar to ‘size’. F# really helps to keep complexity at manageable level. Anyway, I needed to choose one…

Finally, I have chosen FSharp.Compiler.Service project for analysis (It is a relatively new project). I have no idea what is inside, so it will be more interesting to explore source code in such unusual(for me) way. It is an extremely cool project, which is probably one step further for F# and a fundamental improvement that will open a lot of new doors. (You can read more about what it for and what it can do on the official F# Compiler Services site). This project must be large enough and complicated because it is a brand new extended version of the powerful compiler.

ndepend_homeX

Joking aside! Let’s go deeper to the code.

ndepend-dependencies

In the dependency graph picture, we see the primary assembly FSharp.Compiler.Service (orange in the picture). This assembly depends on minimal set of assemblies from .NET framework (they are marked blue). Also we see that this GitHub project contains sample projects that are built on top of the compiler service (marked green). So project structure is simple enough and quite clear. The same dependencies we can visualize as a dependency matrix:

ndepend-dependencies-matrix

In this matrix, we see more quantitative data about dependencies. Numbers in the cells show the number of assembly members used by one assembly from another. Using these numbers, we can make some conclusions like “UntypedTree sample uses more functionality from FSharp.Compiler.Service than others” or “FsiExe is only one sample that has Windows Forms user interface”.

NDepend also provides one crazy interesting report – Treemap Metric View. This report is able to build a tree of namespaces where size of each node will depend on number of LOC in this namespace. Such plots can show where all complexity is concentrated. To extract more useful information from this plot, you need to have an understanding of the code.

VisualNDependView

Finally, the most intriguing part, the analysis dashboard:

NDependDashboard

Based on these stats, we see that FSharp.Compiler.Service contains more than 84.000 lines of code, which is really a lot for F# project; the average method complexity is 3 that is pretty nice. Also NDepend found violations of 12 critical rules, let’s see deeper what they are.

NDepend_violatedRules

Unfortunately, NDepend does not support navigation to method declaration for non-C# compiled source code and this fact complicates observion of F# code.

NDependSourceDeclarationTo avoid this error (for methods) you need to open instance of VS with your solution and NDepend navigate you directly where you wish.

Let’s dwell on critical violated rules:

Code Quality:

Methods with too many parameters – critical

This rule is violated when methods contain more than 8 parameters. I am going to agree here with NDepend – F# compiler source code has such sin. I do not know exact reason of it, but it should be reasonably for compiler/parser source code.

Methods too complex – critical

This rule is violated when methods have ILCyclomaticComplexity > 40 and ILNestingDepth > 4. As I see this happens mostly because NDepend does not understand definition of functions inside other functions (That does not supported by C#). Most of the code that violate this rule is pretty readable. Yes, functionality is wrapped into one large method, but inside it is split into small handy readable functions.

Types too big – critical

This rule is violated when types contain more than 500 lines of code. This story mostly not about F# too. F# compiles modules to the .NET classes. You are allowed to have as large modules as you need. Modules are more like namespaces than classes and constrain with 500 LOC is not applicable for them.

Object Oriented Design

Do not hide base class methods

The rule is self-explanatory. But in current case we should not pay attention because these 3 violations happened in source code of ProvidedType where this is a part of magic of type providers.

Architecture and Layering

Avoid namespaces mutually dependent

I am not sure here, but it also looks like issue related to the F# modules. NDepend reasoning about namespace dependencies without regards to that namespaces are divided into modules.

Dead Code

Potentially dead Types, Methods and Fields

Hmm… It really looks like that there are some methods inside the compiler that were implemented but not used inside and not exposed to external world. It is probably a secret weapon of F#, sketches of new coming features.

Visibility

Constructors of abstract classes should be declared as protected or private

This issue is related to uses of F# discriminated unions. F# compiles discriminated unions into class hierarchy, where root abstract class has a default parameter-less constructor with default visibility (that is internal for F#)

Naming Conventions

Note that C# and F# have a different development guides with a bit different naming conventions.

Avoid having different types with same name

Mostly this rule is also violated by F# modules. It is side effect of F# modules compilation.

Exception class name should be suffixed with ‘Exception’

Exception suffix is rarely used in F# because language has a special exception keyword to define F# exceptions.

Interface name should begin with a ‘I’

F# compiles types to interfaces when all members are abstract. Actually, sometimes we forget to mention I.

Conclusion

Finally, NDepend is a really nice tool. It has some barrier of entry that forces you to refer to documentation, but it looks like a very powerful tool in skillful hand. It is absolutely invaluable in C# world when you want to understand what the hell is going on in the code, but also applicable to F# to see the big picture.

NDepend is highly customizable. Default set of code verification rules is targeted to C# source code, but you can modify existing rules and/or create new ones that will be designed to F#.  Hopefully, one day such rules will become available in default distribution and F# will be officially supported by NDepend team.

P.S. I have tried only a basic feature set; you can read more about advanced features in the official documentation.