Quantcast
Channel: F# monologue
Viewing all articles
Browse latest Browse all 48

An adventure journey of Functional Programming and F# 2.0 in Visual Studio 2010: Part 7 of 17

$
0
0

Hello there!

This blog of F# contains full (long) blog posts of adventure in functional programming and F#. I call it adventure, because I’ll try to make F# as fun to as possible to learn.

NOTE:

This blog is starting to use Visual Studio from Visual Studio 2012 and Visual Studio 2013 (from Release Candidate to RTM), and provide hints of F# 3.0 in Visual Studio 2012.

Now, here are the parts:

  1. Part 1: Introduction to Functional Programming
  2. Part 2: Functional Programming Concepts
  3. Part 3: Introduction to F#
  4. Part 4: Functions, Delegates and Computation expressions in F#
  5. Part 5: F# standard libraries
  6. Part 6: OOP in F#
  7. Part 7: Using LINQ in F# (you are here)
  8. Part 8: F# Asynchronous workflow
  9. Part 9: F# MailboxProcessor
  10. Part 10: Units of Measures
  11. Part 11: F# Power Pack
  12. Part 12: F# for Silverlight 4 (and above)
  13. Part 13: A look at F# 3.0 in VS 11 (Visual Studio 2012)
  14. Part 14: A look of Functional Programming in VB 10 and C# 4.0 compared to F#
  15. Part 15: A look of F# compared to Haskell, Scala and Scheme
  16. Part 16: F# future and what features that F# must have
  17. Part 17: Retrospective


Using LINQ in F# 3.0

Before F# 3.0 in Visual Studio 2012, LINQ was not available in F#. If you use F# Powerpack for F# 2.0, LINQ was implemented as computation expression.

An overview of LINQ

LINQ stands for Language INtegrated Query. LINQ has its first release in C# 3.0 and VB 9.0 in Visual Studio 2008.

Basically, LINQ is a syntactic sugar on top of C# 3.0 and VB 9.0. It is then translated by the compiler into a series of extension method calls to Enumerable (for LINQ to Object) or Queryable (for LINQ to SQL, LINQ to Entity).

Let’s look at LINQ to Object, because this is the basic foundation of all other LINQ to others.

LINQ to Object is the basic foundation because it is available for the basic foundation of all generic or typed collection in .NET: IEnumerable<T>

Why? There are always misconception that LINQ is a mean to connect to database, and the fact is not that! LINQ is a way to query a collection of data. The data can be a single type or can be a collection.

I can also query the running processes on my machine that consumes memory more than 1 MB: (using C#)

csharp_LINQ

In VB, we can also do that:

vb_LINQ

Now we can prove that LINQ is not used only to query database.

The interesting point of using LINQ is, the from, where, select is used as keywords. The compiler will translate those LINQ keywords into series of Lambda expressions.

In C#, the code will be translated into: (the commented is the original source code)

csharp_LINQ_lambda

If you see the source code very well, you’ll also notice that there are type inferences in action! But the type inferences in C# and VB are different with F#.

In C# and VB, type inferences are happened in local scope, and also for method’s parameter but not for the method return type.

F# will deduce an infer the return type of the method gracefully and flows nicely outside the scope of the methods.

F# 3.0 LINQ query expressions

Let’s dive into F# 3.0 LINQ!

LINQ in F# 3.0 was composed using monad builder, by a class names QueryBuilder. The complete fully qualified class name is Microsoft.FSharp.Linq.QueryBuilder. Don’t worry, you don’t have to use it directly because it’s composed for us to be used nicely as composable query.

In F# 3.0 the code will be:

fsharp_LINQ_simple01

The interesting aspect is the use of Seq.ofArray. Let’s say we’ll delete the use of Seq,ofArray, run the code, and display the result using the F# interactive:

fsharp_LINQ_without_seqofarray

Now with Seq.ofArray added, the result is much simpler and also nicer to observe:

fsharp_LINQ_with_Seqofarray

Without Seq.ofArray, the F# interactive will display all of the resulting array of Process.GetProcesses after it display the result of running process. Because the basic behavior of GetProcesses is eager evaluation, not lazy evaluation. Seq.ofArray pipeline will execute it lazily, only evaluate it as needed.

The type inference will infer that array of Process is a derived from IEnumerable<Process>. It is also true in C# and VB.

In the F# code, I also use sortByDescending to sort the result descending, based on the size (using property of WorkingSet64). It is equal to order by in C# and VB with descending option added.

What about the semantic? The semantic is the same, only few clause has different semantic.

This is the table of semantic and syntax differences between C#, VB and F#:

fsharp_LINQ_featurecompare

Notes:

All of the aggregates are not available in LINQ of C# and VB in a query comprehension. F# has integrated in the query computation, as with other SQL clauses (FROM, SELECT, WHERE, JOIN, GROUP BY).

Those query operations that has no semantic differences are really having the same calls to the same methods of LINQ to object. Having no semantic differences means that it’s guaranteed for F# to have the same results as in C# and VB.

We have known SELECT, WHERE, and ORDER BY in F# and a hint of “take”. They are very simple to use, and it has the same semantic although the syntax of ORDER BY in F# has different name, using sortBy.

This is F#’s groupBy in action:

(I intentionally group the processes by ProcessName, and then display the number of grouped process)

fsharp_groupby

As usual, svchost has the largest number of instances.

Note:

The groupBy sample has Count(), and this require System.Linq.
Iterating the result of group by requires us to look at the Key collection first, then the grouped data. Why?

Due to the returned result of groupBy is the same as Enumerable.GroupBy, that returns a IDictionary<Key,Value>.

It returns a dictionary because of the nature of group by: the result is grouped by a key, then each key will have values that grouped by the key.

Now, I’m going to display the maximum amount of memory taken by those process.

This is the code using maxBy:

fsharp_LINQ_maxBy

Those equalities of query operators table is not displaying all, actually. But it can be considered the same as the operations in System.Linq.Enumerable extension methods.


Further readings


Viewing all articles
Browse latest Browse all 48

Trending Articles