We are happy to announce that F# for C# Developers, by Tao Liu (ISBN 9780735670266) is now available for purchase! Please read on for preordering information, a link to the free sample chapters, and an excerpt from the book. The Contents at a glance, the foreword, and an excerpt from the Introduction can be found in this earlier blog post.
Order from O’Reilly click here
Order from Amazon click here
Order from Barnes & Noble click here
Order from Ada’s Technical Books and Café click here
Download sample chapters from the Microsoft Download Center click here
In this chapter, I’ll compare and contrast various data structures from F# and C# programming languages. F# is a powerful multiparadigm language that supports imperative, object-oriented, and functional programming. C# is a multiparadigm language with more of a focus on imperative and object-oriented programming. A C# program usually consists of statements to change the program’s state. An imperative language describes how to finish a task with exact steps. A functional-first language, like F#, is more declarative, describing what the program should accomplish.
One example of a programming language adopting functional programming is the C# version 3.0 introduction of LINQ (Language INtegrated Query). The growing popularity of Scala and Closure shows functional programming is growing. In addition, F# is another tool Microsoft ships with Microsoft Visual Studio to solve ever-changing programming challenges. Which language you choose to use depends on your experience and environment, but keep in mind you do not need to make an exclusive selection. I hope this book provides some information that helps you make appropriate decisions. Any programming language is designed to perform some computation and to process data. The way that data is organized and stored is referred to as the data structure. This chapter introduces basic data structures for F#, explains how they relate to C#, and details how you can apply them to create imperative programs. I will follow the tradition in programming books of presenting a Hello-World-like application to introduce a new language. I will provide simple C# code along with the F# imperative equivalent.
Listing 1-1 shows an imperative approach that simply adds up the odd numbers from 0 to 100. C# supports functional programming (such as a LINQ feature), and there is a more concise way to implement the same functionality, which I’ll show later in this chapter.
LISTING 1-1 A C# snippet that adds odd numbers from 0 to 100
By porting this C# code to the F# equivalent, I’ll cover the follow topics: ■ The basic data type (such as primitive type literals). See the “Basic Data Types” section. ■ The if, while, and for syntax. See the “Flow Control” section.
After implementing the same functionality in F#, I’ll cover some F# data structures, such as Seq and tuple. Although this particular sample does not require Microsoft Visual Studio 2012, it is highly recommended that you install it, which is the minimum requirement for various samples in this book. I’ll also introduce F# Interactive and some other useful add-ins to improve your overall F# programming experience.
Now it’s time to start our journey!
F# is a .NET family language; therefore, the basic type definition and reference are similar to C#. Table 1-1 lists the C# and F# data types as well as the way to define a variable with each type. F# is a strongly typed language. Any errors related to type conversion are reported at compile time. These errors can be detected at an early stage of development and checked, which enables them to be fixed at compile time. One big difference between the C# and F# definitions is that the F# examples do not need an explicitly defined type. This is because F# is often able to infer a type from the assigned value. To most C# developers, this feature is a lot like the var keyword in C#. There are some fundamental differences between var and let, but you can think of them as equals for now.
TABLE 1-1 Basic data types
One particular F# feature I’d like to call out is the syntax for creating an array of bytes to represent an ASCII string. Instead of asking you to constantly call into the Encoding.ASCII.GetBytes function, F# provides the “B” suffix to define an ASCII string. The string in .NET is Unicode-based. If you are mainly programming an ASCII string, you will not like this. In the following code, the representation for asciiString is a byte type internally:
let asciiString = "abc"B // F# code byte asciiBytes = Encoding.ASCII.GetBytes(value); // C# code Unlike C#, float in F# is a double-precision floating point number, which is equivalent to a C# double. The float type in C# is a single-precision numerical type, which can be defined in F# via the float32 type. The .NET 32-bit and 64-bit floating numbers can be positive infinite or a NaN value. F# uses shortcut functions to represent these values: ■ Positive Infinity infinity is System.Double. PositiveInfinity and infinityf is System.Single. PositiveInfinity ■ NaN nan is System.Double.NaN and nanf is System.Single.NaN The F# compiler does not allow any implicit type conversion. For a C# developer, an integer can be converted to a float implicitly, and this gives the impression that 29 is the same as 29.0. Because implicit conversion is not allowed in F#, the explicit conversion float 29 is needed to convert the integer 29 to a float type. The explicit conversion can eliminate the possibility of lose precision when the conversion is implicit.
F# 2.0 had two syntaxes for strings: normal strings, and verbatim strings, which are prefixed by the at sign (@). F# 3.0 introduces a new feature to define strings using a triple-quoted string.
F# supports normal strings and verbatim strings. This is equivalent to the options that C# provides. Examples of normal and verbatim string definitions are shown in Listing 1-2. The execution result shown in the listing is an example of a normal string and verbatim string being bound to specific values within the F# Interactive window (which I’ll introduce shortly in the “Using F# Interactive” section). The result shows the variable name, type, and value. LISTING 1-2 Normal and verbatim strings
let a = "the last character is tab\t" let b = @"the last character is tab\t"
Normal and verbatim strings are useful for a variety of tasks. However, scenarios that require included characters, such as double quotes, are still difficult to implement because of the need to escape these characters. Listing 1-3 shows examples of this. LISTING 1-3 The escape double quote (“)
F# 3.0 introduces a new string format—a triple-quoted string—that alleviates this pain. Everything between the triple quotes (“””) is kept verbatim; however, there is no need to escape characters such as double quotes. Triple-quoted strings have a number of use cases. A few examples include the creation of XML strings within your program and the passing of parameters into a type provider. Listing 1-4 shows an example.
LISTING 1-4 A triple-quoted string
How to define a variable name is a much-discussed topic. One design goal for F# is to make variable names resemble more normal human language. Almost every developer knows that using a more readable variable name is a good practice. With F#, you can use double-backticks to include nonalphabet characters in the variable name and eventually improve the readability of your code. Examples are shown in Listing 1-5. LISTING 1-5 Defining a variable
To read more, please check out the sample chapters for this book.
How about something more idiomatic like:
[0 .. 100] |> List.filter (fun i -> i % 2 = 0) |> List.sum