Tools are the lifeblood of any programming language, and F# is no different. While you can be successful writing F# code in your favorite text editor and invoking the compiler exclusively from the command line, you’ll likely be more productive using tools. Like C# and VB.NET, F# is a first-class citizen in Visual Studio. F# in Visual Studio has all the features you would expect, such as debugger support, IntelliSense, project templates, and so on.
To create your first F# project, open up the Visual Studio IDE and select File→New Project from the menu bar to open the New Project dialog, as shown in Figure 1-1. Select Visual F# in the left pane, select F# Application in the right pane, and click OK.
After you click OK in the New Project dialog, you’ll see an empty code editor, a blank canvas ready for you to create your F# masterpiece.
To start with, let’s revisit our Hello, World application. Type the following code into the F# editor:
printfn "Hello, World"
Now press Control + F5 to run your application. When your application starts, a console window will appear and display the entirely unsurprising result shown in Figure 1-2.
It may be startling to see a program work without an explicit
Main method. You will see why this is
admissible in the next chapter, but for now let’s create a more
meaningful Hello, World–type program to get a feel for basic F#
The code in Example 1-1 will create a program that accepts two command-line parameters and prints them to the console. In addition, it displays the current time.
Example 1-1. Mega Hello World
(* Mega Hello World: Take two command line parameters and then print them along with the current time to the console. *) open System [<EntryPoint>] let main (args : string) = if args.Length <> 2 then failwith "Error: Expected arguments <greeting> and <thing>" let greeting, thing = args., args. let timeOfDay = DateTime.Now.ToString("hh:mm tt") printfn "%s, %s at %s" greeting thing timeOfDay // Program exit code 0
Now that you have actual F# code, hopefully you are curious about what is going on. Let’s look at this program line by line to see how it works.
Example 1-1 introduces three values named
thing= args., args. let
timeOfDay= DateTime.Now.ToString("hh:mm tt")
The key thing here is that the
let keyword binds a
name to a value. It is worth
pointing out that unlike most other programming languages, in F# values
are immutable by default, meaning they
cannot be changed once initialized. We will cover why values are
immutable in Chapter 3, but for now it
is sufficient to say it has to do with functional programming.
let number = 1 let Number = 2 let NUMBER = 3
You can enclose the value’s name with a pair of tickmarks, in which case the name can contain any character except for tabs and newlines. This allows you to refer to values and functions exposed from other .NET languages that may conflict with F# keywords:
``this.Isn't %A% good value Name$!@#
Other languages, like C#, use semicolons and curly braces to indicate when statements and blocks of code are complete. However, programmers typically indent their code to make it more readable anyway, so these extra symbols often just add syntactic clutter to the code.
In F#, whitespace—spaces and newlines—is significant. The
F# compiler allows you to use whitespace to delimit code blocks. For
example, anything indented more than the
if keyword is considered to be in the body of
if statement. Because tab characters can
indicate an unknown number of space characters, they are prohibited in
You can configure the Visual Studio editor to automatically convert tab characters into spaces by changing the relevant setting under Tools→Options→Text Editor→F#.
Reviewing Example 1-1, notice that the
body of the
main method was indented
by four spaces, and the body of the
if statement was indented by another four
let main (args : string) =
if args.Length <> 2 then
failwith "Error: Expected arguments <greeting> and <thing>"
let greeting, thing = args., args.let timeOfDay = DateTime.Now.ToString("hh:mm tt") printfn "%s, %s at %s" greeting thing timeOfDay // Program exit code 0
If the body of the
failwith, was dedented
four spaces and therefore lined up with the
if keyword, the F# compiler would yield a
warning. This is because the compiler wouldn’t be able to determine if
failwith was meant for the body
[<EntryPoint>] let main (args : string) =
ifargs.Length <> 2 then
failwith"Error: Expected arguments <greeting> and <thing>" Warning FS0058:
possible incorrect indentation: this token is offside of
context started at position (25:5). Try indenting this token further or
using standard formatting conventions
The general rule is that anything belonging to a method or
statement must be indented further than the keyword that began the
method or statement. So in Example 1-1, everything in the
main method was indented past the first
let and everything in the
if statement was indented past the
if keyword. As you see and write more F# code,
you will quickly find that omitting semicolons and curly braces makes
the code easier to write and also much easier to read.
Example 1-1 also demonstrated how F# can interoperate with existing .NET libraries:
open System// ... let timeOfDay =
The .NET Framework contains a broad array of libraries for
everything from graphics to databases to web services. F# can take
advantage of any .NET library natively by calling directly into it. In
Example 1-1, the
DateTime.Now property was used in the
System namespace in the
mscorlib.dll assembly. Conversely, any code
written in F# can be consumed by other .NET languages.
For more information on .NET libraries, you can skip ahead to Appendix A for a quick tour of what’s available.
//Program exit code
(*Mega Hello World: Take two command line parameters and then print them along with the current time to the console.
For F# applications written in Visual Studio, there is a third
type of comment: an XML documentation comment. If a comment starting with three slashes,
///, is placed above an identifier, Visual
Studio will display the comment’s text when you hover over it.
Figure 1-3 shows applying an XML documentation comment and its associated tooltip.