Visual Studio 2008 and F#

Once I downloaded and installed Visual Studio 2008 Team System in this laptop, one of the first things I did was to install F# to see how well it worked in the shiny new IDE. It worked without any hassle and to celebrate I wrote a typical business example: get the average salary of a group of employees.

First some preparatoy work: lines 3 to 7 define a F# record with 4 fields; lines 9 to 13 fill an employee list (not an array, mind you, but a variable length list).

The interesting stuff starts at line 15, the average function takes a list of numbers and returns, well, its average, in this way:

  • If the list is empty it just returns 0
  • In any other case it adds up all the elements in the list (the fold1_left function accumulates all the elements using '+') and divides the result by the length of the list.

Finally, the averageSalary functions takes a list of employees and:

  • Extract their salaries into a list (this is done by the salaries function which is defined locally inside averageSalary)
  • Apply the average function to the salary list

A conosseur may argue that there are better ways of implementing the salaries function, but I didn't want to burden you with more functional delicacies. So, what do you think of this way of programming as compared to C#, VB.NET or Java?

13 Comments

  • Hi Edgar,

    While I appreciate you are *implementing* average in a functional way - I think the message will be lost on most C# programmers who will just look at your companyRoll assignment and figure in C# via a standard query operator they can do the same thing:
    var averageSalary = companyRoll.Average(e=>e.salary);

    Maybe you can do another example that is not one of the standard query operators?

  • Hi David,

    Ah, LINQ! You've really got me here! I guess in my eagernes to show a simple example of F# in a "business scenario" I totally miss the LINQ forest for a few functional trees (well, lists...)

  • There's a couple of things you can do to make the F# more like the LINQ. First you can place most averageSalary function with a map then pipe the results of this to your average function:

    let averageSalaries =
    companyRoll
    |> List.map (fun emp -> emp.salary)
    |> average

    But the LINQ average function is very similar to the average function defined in the example, except the LINQ version except the LINQ version takes a project function, which can easily be added to the F# version:

    let average numbers project =
    match numbers with
    | [] -> 0.
    | _ -> (List.fold_left (fun acc x -> acc + project x) 0.0 numbers) / (float numbers.Length)

    let averageSalaries = average companyRoll (fun emp -> emp.salary)

    And of course you can always use the LINQ functions from F#.

  • As someone with no knowledge of F# programming an a basic knowledge of languages like Java and C# I look at the F# code and say "What?!".

    It is completely unclear to me that "average" is a function, what it's parameters are and what it returns. Same is true for "averageSalary".

    It's probably just that I don't get F# but it may as well have been written in Greek. Even Perl would have been easier to understand.

  • I have to agree with Anon up there.

    From some one who has used a lot of different languages, the syntax of F# definitely leaves something to be desired.

    I thought that the days of writing new languages that use nothing but cryptic symbols was over... I mean, you should not be able to write an entire line of code using all symbols: | [] -> [] is not acceptable.

    Why use semicolons instead of commas to separate items in a list?

    Where do the functions end and arguments begin?

  • Yea, I agree with Anon... I have no clue what it is doing.

    But, the syntax does look somewhat clear. I guess I'm just not sure how all the operators, et al work in F#. I have purchased the book "Foundations of F#" but I haven't opened it yet (had it for a few weeks now).

    Some of the syntax reminds me of Delphi, a little :)

  • Josh. F# seems to be a functional programming language with a syntax that looks a lot like ML. Judging from the syntax currying is supported so it is hard to distinguish between a function and its arguments.

    Also [] -> [] is _very_ acceptable :-)

  • I think your sample is good, but judging from the feedback I saw, I would heavily explain each section of your code.

    e.g.

    type employee, this is a type definition (similar to a struct)

    companyroll, a linked list of instances of the employee type

    let average = match(...

    This is pattern matching in F#. This section will average over an F# Linked List of numbers and obtain the average value

    let averageSalary employees = rec salaries employees...

    This is also pattern matching in F# over a list. The purpose of this code is to take all of the salaries out of the list of employees and place them in a List of salaries. The function recurses through the list and concatenates the salary to the front of the list.

    average (salaries employees) is an example of currying function. the salaries recursive function is called with the list of employees and returns a list of salaries as floats. average is then called on the list of salaries to obtain the average salary of the employees.




  • And how does that mean? I do not understand anything.

  • WRDGRA Very good blog post. Fantastic.

  • cC98D6 Appreciate you sharing, great post.Really looking forward to read more. Really Cool.

  • GRSigE Thanks again for the article post.Really looking forward to read more. Really Great.

  • P6Vo61 Appreciate you sharing, great article post. Will read on...

Comments have been disabled for this content.