Types and Output

Hello World

In a console environment, such as fsi.exe a "Hello World" program is very simple, the programmer has only to enter the string “Hello World” and the console will echo it back.

> "Hello World";;
- : string = "Hello World"

Example 1 - The string "Hello World" entered in to the fsi console.

If the F# compiler is given a source file containing just the string “Hello World”, that is, the equivalent of example 1, it will not report a parse error. A source file containing the code from example 1 will compile without errors, but upon executing the resulting program nothing will be output to the console. This is because stand-alone programs do not automatically echo their results to the console. If the programmer wants to a string to be output a function must be called to achieve this. These function calls must be part of assignments to labels, but assigning these functions to labels will have no direct effect as these functions have no return values. The string is output as a side effect of the function.

let text = "Hello World"

(*
The string assigned must then be output to the console.
This section uses F# built-in functions to achieve this.
*)
let _ =
     print_string(text);
     print_newline()
(*
It is also possible to access the console via the .NET methods.
*)
let _ =
     System.Console.WriteLine(text)

Example 2 - An F# Hello World program

F# has a number of built-in functions designed to output values to the console. Examples of these, print_string and print_newline, can be seen in example 2. As these functions have no return values they have been assigned to the label "underscore" (_). This is a naming convention meaning that there is no interest in the value assigned to that label.

The second part of example 2 shows two things, that labels can be reused and that functions from the .NET framework can be called using their fully-qualified names.

Types and how to output them

F# has a number of litterals built-in; the most basic of these these are string, bool, int, float and char, which are summerised in the table below. These types are based on types in the .NET framework. In F# there is generally no need to declare what type you are using; the compiler can work this out for you. It is possible to explicitly give a label a type by using a colon (:) and then the type name, but this is usually unnecessary.

F# type Example F# Literal Declaration .NET Framework type
string "My string" System.String
int 9 System.Int32
float 3.14 System.Single
char 'a' System.Char
bool true System.Boolean

Table 1 - summary of F# basic types

F# has a number of functions for outputting different types of data to the console. There is no implicit casting in F#, but there are built-in functions to convert most of the basic types to other basic types, so a programmer could convert a non-string type to a string and use the .NET framework methods to output it. A programmer has a number of choices about how to output data to the console. The listing below demonstrates a number of them.

open System

let str = "Test"
let character = 'a'
let boolean = true
let integer = 12
let floatingPoint = 1.01

let _ =
     Console.WriteLine ("Testing conversion to string then output via .NET console ...");
     Console.WriteLine ("string: " ^ str);
     (*
     Note: F# doesn't have a string_of_char method, but you can
     use String.make to have a similar effect.
     *)
     Console.WriteLine ("char: " ^ (String.make 1 character));
     Console.WriteLine ("bool: " ^ string_of_bool(boolean));
     Console.WriteLine ("int: " ^ string_of_int(integer));
     Console.WriteLine ("float: " ^ string_of_float(floatingPoint));
     print_endline "Testing output though native functions ...";
     print_string "string: "; print_string str;
     print_newline();
     print_string "char: "; print_char character;
     print_newline();
     print_string "bool: "; print_any boolean      print_newline();
     print_string "int: "; print_int integer;
     print_newline();
     print_string "float: "; print_float floatingPoint;
     print_newline();

Different types being output to the console

The other thing to note from this listing is use of the keyword "open". An F# programmer can use the keyword open in much the same way a C# programmer uses the keyword “using”, it’s a shortcut to avoid having to qualify classes with namespaces.