Published: 05 Apr 2010
By: Manning Publications

This article is taken from the book F# in Action. The authors discuss basics of imperative programming in F# and develop a simple application to show how this type of programming works. They also feature some of the interoperability among languages on .NET platform.

Contents [hide]

About the book

This is a sample chapter of the book F# in Action. It has been published with the exclusive permission of Manning.


Written by: Amanda Laucher and Kevin Hazzard
Pages: 425
Publisher: Manning
ISBN: 9781935182252

Get 30% discount

DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code dns30 at checkout.

Introduction

F# is a fully supported .NET language. This means that it is will be available in Visual Studio 2010. If you are running Visual Studio 2008, you can still use F#, but you have to install it first from the MSI available on Microsoft's website.

We'll take this opportunity to become familiar with a bit of the F# syntax. You'll see the basics to beginning imperative programming in F# and an actual application that is going to be very imperative. Most of the syntax will be new, but the concepts should be either familiar or very simple to understand.

Some F# imperative basics

So, let's discuss some simple data constructs, classes, and control flow. By the end of this subtopic you should feel comfortable starting up an editor and digging into the code. You should also begin to be able to read at least the code that you find in other resources.

Arrays

Arrays in F# are just like arrays in other languages. They are mutable by default. What good would an array be if they were immutable? Think about the effects of mutability for quick access of an item in the middle of the array. Arrays are defined as follows:

Let arrayName = [|item1;item2;item3|]

They are used a lot less in F# than what you might be used to. F# and functional programming languages tend to focus more on lists. Lists are defined the same as arrays, only without the "|" next to the brackets.

Records

We often want to be able to assign an identifier to groups of values and give each of those values a name. Take, for instance, if we want to store some data in a database table, we will give the table a name and then give each column in the table a name. We can replicate this type of organization using a record. Many simple objects can be defined using records, as seen in Listing 1.

Listing 1: Record syntax

type Person = { Name : string; mutable City : string; Age : int} #2

We define a record using the keyword "type" and the assigning an identifier as shown below. Following the "=" is where we define the named parts, or fields and their types after a colon. Each field and type is separated with a ";". Listing 2 will show different ways of creating new instances of record types.

Listing 2: Creating an instance of a record

As you can see, there are two ways of creating a new instance. You can do the simple way, or the long way which is seen in . Fields which have been defined as mutable can be updated with the left arrow (<-). The return value of an update is of type unit.

What's interesting about records is that properties are automatically created for the fields defined. This is one of the many ways that F# saves keystrokes. You can see that this is true by using an MSIL disassembler such as Ildasm.exe (Microsoft) or .NET Reflector (redgate). In the next subtopic we will learn to write classes that will behave like C# classes.

Classes

Classes are a basic object-oriented (or as we are most used to seeing today, class- oriented) way of organizing code. They are used to define or extend .NET objects. We use classes in F# when we are focused on interoperability with external libraries and not as the default choice. Listing 3 shows the class definition syntax as shown in the MSDN Developer Center.

Listing 3: Class definition

Classes are defined with the keyword type. The parameters are constructor parameters. Types are also created using the type keyword. The lines between the class and end keywords define the class. The keywords themselves are optional. The inherit keyword is how you can go about defining a base class. The keyword let is used to define the local functions and fields of the class. The do bindings are important because they contain the code you wish to execute upon the construction of the object.

Members make up the public interface of a class. They are instance and static method declarations, interface declarations, abstract bindings, and property and event declarations. Members are public by default, and unless otherwise specified. They define the public interface to the type. You can define types that are dependent on each other using the keyword and. It is important to know at this point that you can define classes and use them the same way you do in other .NET languages. They are used far less in F# than in other languages because of the availability of other constructs such as records, and discriminated unions which you will see in the next chapter.

It is common to need to delimit several distinct value possibilities of the same type as an enumeration in imperative programming. We will walk through that in the next subtopic.

Enumerations

Enumerations or enums are the same in F# as they are in C# or VB.NET – a way of describing a set of named values of a specific type. Each named value is called an enumerator. Each enumerator behaves as a constant. An identifier that is of the enumerator type can be assigned any of the enumerator's values. Listing 4 shows an example of enumeration in F#. The keyword type is used in the definition, as seen in #1, followed by the name of the enum and the specified values. You can see the use of the enum in #2 and the return value in #3 is of type Direction.

Listing 4: Enumeration example

The keyword type is used in the definition, followed by the name of the enumeration and the specified values. You can see the use of the enumeration and the return value is of type Direction. The enumeration can now be used just as any type would throughout the application.

Enumerations are very similar to the discriminated union type in functional languages. They are defined in pretty much the same way, but they are closer to the union type in the C language.

We have looked at enumerators, classes, functions, and data constructs but all of this can be very limited without the ability to control the flow of the application. We'll discuss the different types of control flow in the following subtopic.

Control flow

We've talked a bit about creating containers for data and basic functions, but all of that can be pretty useless without some way to control the flow of the code. In this subtopic, we'll take a look at conditionals and looping constructs. Note that we'll look at the basics that are common in imperative languages to give you a look at how to do what you are already familiar with in other languages.

If/Then/Else

If/Then/Else works much like it does in other languages. The expression after the if is evaluated. If the result is true, it will execute and return what is after the then. If the result is false, it will fall down through the elif expression. If none of the values are true, it will evaluate the expression after the else. All branches of conditional expressions must have equivalent types. This means that an expression after an else cannot return an int, while all of the expressions after the if or elif return a string. They must match. The syntax is written in Listing 5. You can see an example of printNumber function, which takes in a parameter num and returns a unit. Notice that the way the scoping works is the same as in other functions. Whitespace determines what will happen in which case. The string will print every time the function is called regardless of the parameter passed.

Listing 5: If/Then/Else

Any expression that returns a Boolean value can be after the if, or elif. You can also use the Boolean operators shown in Table 1 between expressions.

Table 1: Boolean operators in F#

Operator

Description

Not

Boolean negation

||

Boolean or

&&

Boolean and

The next control flow construct that is important is a while loop. We'll discuss it in the following subtopic.

While Loop

The while loop is a common imperative control flow construct. As long as the expression after the while evaluates to true, the expression before the done will execute. The syntax and an example can been seen in the listing below. You can see in the example that the conditional operators can also be used as listed in Table 1.

Listing 6: While loop

While loops always are of type unit. You can see the do expression within the looping construct, telling the compiler that the following code is imperative and will return a unit.

The for loop goes hand in hand with the while loop but it is used much more often in functional expressions. We'll take a look at it in the next section.

For loop

The for loop is a way to execute some code a certain number of times. The syntax is shown in the listing below #1. The code between the do and the done will execute once for each of the items in 0 to allOfThem. The for loop in F# is much the same as that in other .NET languages. Like while loops, for loops also return unit. The do keyword is used again before the imperative expressions. You can also use for..to and for..in to specify executing the function once for each item in a collection.

Listing 7: For loop syntax and example

This will cover many of the basics needed to start an imperative application. We should use the syntax that we know to build something familiar. In the next topic we'll look at building an application.

A Windows Forms Application explained

Now that we have a solid understanding of imperative F# code, we can take a look at an actual application. The code written in this topic will be very imperative. There will be some syntax that may not have been covered but the concepts should be familiar. I'll point out where new syntax is important. Before we start, I should mention that, although I prefer code with my tests first, I'll not show the tests in all of my code samples. Tests will be available with the code included on the book's Web site.

First, let's take a look at what we are going to build. This will help you understand the outcome and allow you to consider what the code might look like according to what we already know. Below is a screenshot of the completed form.

Figure 1: Screenshot of a running application

Screenshot of a running application

You can see that the form itself is fairly simple. It contains a few text boxes, labels, a button, and a web browser control. Remember that there is no designer for F#, so the code must all be written manually. This isn't the most exciting task, but I think it gives a good comparison of syntax. You'll notice that F# is much more concise than other languages that we're used to seeing.

Our task will be to count the number of times the user types the Yahoo, Google, and other addresses into the URL text box and clicks Go. We'll tally each count and display it to the screen. Can you imagine what the C# or VB.NET code looks like?

To get started, we'll create a new F# application from a template. Open Visual Studio, click File from the menubar, and then New Project. In the Templates list, select F#, click New Application, and click OK. This will open a new project and a file where we can type some code.

Listing 8: Add code to reference external libraries

The first code we'll need is a few open statements shown in Listing 8. We use open like we would using in C# or imports in VB.net. It's the way we access external libraries. After you have added an open statement for a namespace or module, you must also add the reference to the project. Do this by right-clicking the Reference section within the project and select Add Reference, as seen in Figure 2.

Figure 2: Adding a reference to a project by right clicking References under the project in the Solution Explorer

Adding 

a reference to a project by right clicking References under the project in the Solution 

Explorer

The next thing we need is a place that we can store the information about the different sites that we want to track. A simple record should work just fine. We will also need a simple helper function to create a Uri from a string. Finally, we will create 3 addresses. Examine the code in Listing 9. Our address type is fairly simple. It has a Name, Url, and Count. The Count is marked as mutable. This is so that we can update it to add one each time the Url is used. Next, we have a function called url. It takes in a string and creates a new Uri from that parameter. The new keyword is used just as it would be in other languages. The last three lines create address records. Notice that the second field, Url is the application of the url function. The string Url is passed to the url function and the Uri is returned. You could replace the function with the Uri value and the result would be the same.

Listing 9: A record type to store information about addresses.

Next, we'll create a form in Listing 10. Again, we use the new keyword and then set some values in the form's constructer. The form's Text is set to the function that gets the time and Visible is set to true. The size is really the only hard part here. Without a designer, you must play around to get things the size that you want.

Listing 10: Code for a new Form

Now it's time for the controls. The code is listed below in Listing 11. The first thing we need is a textbox, , so that the user can enter a Url. Then we will need several labels for the counts and textbox description. Since we have so many labels to create, we can simplify the process by creating a function. It will take in the coordinates for location in the form of a tuple of x and y axis points.

What is a tuple

A tuple is a sequence (or ordered list) of finite length. An n-tuple is a tuple with n elements. Tuples are usually written within parentheses. For example, (2, 7, 4, 1, 7) is a 5-tuple. A tuple in F# is pretty much the same thing; only tuples can contain any type, including functions. The values contained within the tuple are accessed by their position and not a name or an index.

The function will also have a string parameter that will be the text of the label. You can see how this function is used and all of the lines below. This saves us from typing quite a bit of code. You might see how F# syntax makes it easier to think a little bit differently about doing even basic things.

Listing 11: Textbox Code

We'll also need a WebBrowser control. I've decided to do this one a little bit differently. Examine the code in Listing 12. You can see an identifier browser assigned to a multiline expression. We create a new WebBrowser with an empty constructer. Then, in the next lines we update the mutable properties using the left arrow We use the url function which was created earlier and pass it the starting string for the WebBrowser's Url. Finally, we return the browser.

Listing 12: WebBrowser Control Code

We now need to create a couple of EventHandlers to handle the button clicks. The code is listed in Listing 13. First, we need to be able to change the browser's Url to the Url entered in the textbox by the user. We use an anonymous function that takes in two parameters and then updates the browser's url. We have a lot going on so let's break it down so that it is easier to digest.

We'll use the keyword fun that was talked about in section 2.#. EventHandlers have two parameters a sender and eventargs. We can ignore both of those values while still matching the signature required by using the underscore. The underscore is like a wildcard. It's acting as a placeholder in this situation. We'll see it again when we look at pattern matching in the next chapter. Next we have the right arrow (- >) which acts sort of like the equal sign in our lambda. We want to update the url so we'll use the left arrow (<-) to update the mutable value. We must change the string value entered into the textbox into a Url and we can do that using that function the url function that was defined at the beginning of this topic.

In the next function, we create a function that will be called by the EventHandler. We have a multilined function that again takes 2 parameters whose values are ignored. We get the value of the textbox's string as a Url. Then look at the if expression. If the Url value matches the Url in the google record, we update the Count in that record. After the Count is updated, we get the string value and display it in the corresponding label. We do the same thing to check against Yahoo and other address records. We now have two EventHandlers to handle the work needed when the button is clicked.

Listing 13: EventHandler Code

You might remember that we have not actually created the button yet. You can see the code in Listing 14. This is done much the same as the browser. The important part here is adding the EventHandlers. We had to define the EventHandlers first as they cannot be referenced before they are defined. The button is returned in the last indented line.

Listing 14: Button Code

Now, it's time to add all of our controls to the form. I have taken two approaches, shown in Listing 15. We need to look at all of the controls as Controls rather than as their specific type so that we can work with them in a list. For now, it is important to remember that every item in the list must be of the same type. A function takes in a parameter and returns the Control type. Then, all of the labels are put into a list and a higher order function is used to map the function in #1 to each item in the list. This is the same as calling the ctrl function and passing in each item in the list as a parameter. This is a big concept that makes FP very appealing. The return value is a list of Controls.

The next line is a for loop. We take a list of remaining controls and concatenate it to the list of labels. Then, for each Control in the entire list, we call the form.Controls.Add function. Our form is complete!

Listing 15: Adding the controls to the form

One last thing remains. We must run the application. The code for this can be seen in Listing 16. An attribute must be set for STAThread.

Listing 16: Run the application

And, now for a complete show, see Listing 17.

Listing 17: Complete code listing for Windows Form Application

See if you can read and understand what is going on in each line. If it all seems to make sense, you are ready to learn more about functional programming.

Summary

We looked in depth at some of the imperative ideas and some data constructs available in F#. We learned about records and enumerations and how they look in F#. We ended the article with a Windows Forms application that used some of the syntax that we have learned and showed a bit of interoperability among languages on the .NET platform.

Get 30% discount

DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code dns30 at checkout.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Manning Publications

Manning Publication publishes computer books for professionals--programmers, system administrators, designers, architects, managers and others. Our focus is on computing titles at professional levels. We care about the quality of our books. We work with our authors to coax out of them the best writi...

This author has published 33 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Increasing your productivity with Visual Studio 2010
Visual Studio is the program that most of the times a .NET developer is working with. This article c...
Understanding Multilayered Architecture in .Net
This article focuses on understanding a basic multilayered architecture in C#.Net.
Introduction to Android JNI development Using NDK - Part 1
In this first article of this small series, we will try to delve into the Java JNI inner workings an...
Android for .NET Developers - Picklists and listviews
In this article, I'll discuss how to arrange an Android view where the dominant element is the list....
Introduction to Android JNI Development Using NDK - Part 2
In the first part of this series you've learned the fundamentals concerning Java JNI programming. In...

You might also be interested in the following related blog posts


Contract Projections in WCF declarative services read more
What is Softwaremaker doing now ? read more
Entirely unobtrusive and imperative templates with Microsoft Ajax Library Preview 6 read more
The Functional Language Gateway Drug read more
Recommended Reading I read more
Contract Projections in WCF declarative services read more
Have I Missed The Bus? read more
A new generation of programmers begins read more
Software Development Meme read more
Give a session on Parallel Programming (or just learn from it) read more
Top
 
 
 

Please login to rate or to leave a comment.