Learning F# — Part 5 — Hello

We have been testing out F# on the FSI. FSI is a quick way to test out F#’s concepts. Today I want to create a simplest F# application. It will be a console application. It will print a greeting on the console window. I am going to call it the Hello App. I know, I know it should have been the “Hello World” App. I do not have any issues with that. But I want to keep my topic names one worded. The topic name for today is “Hello”, hence my app name is Hello.

Fortunately, F# runs on the .NET platform. There are many advantages to that. But, in short, F# running on .NET means that you can run your applications on most systems including Mac OS X, Windows and Linux and many others. Read more about it here. This why you would need a .NET SDK. There are different implementations of .NET. We are going to use .NET core, because its the coolest one. I am sure you already have it installed if you have followed my previous posts. If not download the dotnet core SDK and install from here .

Kindly note, I will be using a windows machine, simply because I have one. I would love to do the same exercise on Mac, but can’t. But you can still follow on Mac with only minor differences.

Create a folder anywhere you want your code to be and call it “Hello”. Actually the name can be of your choosing, I am choosing Hello, please feel free to follow along. Create a file named “Program.fs”; note the extension “.fs”, that’s the extension for the F# code files. Open the file to edit it. I am using notepad. Feel free to use any simple text editor. Please refrain from using an IDE at this point. This will defeat the purpose of understanding things because IDE will do a lot of things for you. IDEs come with powerful tools and help you with lot of dev chores. For now let’s not delegate the chores to the IDE.

Paste the following code in Program.fs.

open System 
[<EntryPoint>] 
let main argv =
printfn "Hello"
0

Please note the indentation on last two lines. Those are required!. But why, you may ask. Well, F# does not use curly braces for a block of code, instead it uses indentation. This keeps the code succinct. You would thank F# when you have large application. You can choose your indentation size, 1 space, 2 spaces, 3 or 4, whatever you choose keep it consistent. You may notice that main is a function that accepts an argument named argv. The body of the function has 2 lines of code equally indented to indicate that its a block of code belonging to the function to which it is indented from. Okay, lets understand every line.

open System

System is what is called a module in F#. Module is made up of functions. To use a function in a module, it must be opened for use. The System module contains many functions. For our console app, we are interested in one of it’s functions. That function is printfn. It prints out a string on the console window.

let main argv = 
printfn "Hello"
0

These 3 lines form the definition of the function main. It has a body with 2 lines. The last line in the function body is the return statement. This returns the output of the function. In our case 0 is the return value. Why 0? Good question. The return value is meant to be the exit code of the application. Historically, an exit code of 0 means the application exited successfully without errors. You can define your own codes for your application, just make sure the users know about your exit codes. The first line in the function body which executes a function called printfn, is a print function from System, that prints a string to the console. Here we are printing the string “Hello” to the console window. The line with the let keyword, binds the function with the name main. Notice that the function also takes an argument called argv. But we are not using that argument value anywhere. We will in the next example. So when this function is called( executed), “Hello” with be printed on the console window and the value 0 will be returned to whoever had called the function.

[<EntryPoint>]

This is called an attribute in F#. The name of the attribute is in between these [<>]. This is an EntryPoint attribute. Note that in the example, this attribute is right above the function. The EntryPoint attribute adorns the main function. This makes the main to have the signature string[] -> int, i.e. the function takes in an array of string and returns an int. This attribute makes the main function slightly special. This function, because of the attribute it was associated with, becomes the entry point of our application. All applications need a starting point. The point where the execution begins. So when we run this application, this is where the execution starts.

The F# code is ready. Now all we need is a F# project file. F# project is made up of F# code files. In our case we have only one file. Create a new file named Hello.fsproj in the same folder as the Program.fs. Note here that the project file is written in XML. If you are new to XML, take a quick introduction here. It is a simple format to represent information in human readable, yet machine readable, format. Following should be the contents of the fsroj file.

<Project Sdk="Microsoft.NET.Sdk"> 
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>

The top-most element is the <Project> element. This contains other inner elements. It has an attribute associated with it called Sdk. This attribute has a value “Microsoft.NET.Sdk”. We will build the application using dotnet. This attribute tells dotnet which Sdk this project is built on. The next inner element is the <PropertyGroup> element, which holds a group of properties as the name says. The two necessary properties we are going to use are output type and target framework. The output type defines what should the application be like when it is built. We define here that it should be an executable. The next one is the TargetFramework. We are targeting .NET Core and the version is 2.0. Read more about it here. The second element under the <Project> element is <ItemGroup>. This can contain many properties, but we just need one of them i.e. <Compile> with an attribute called Include. This attribute value has the name of the F# file which belongs to this F# project. It is quite easy to understand the project file. Now fire up your command line tool, cmd or powershell or whatever works for you. Navigate to the project folder. To the folder where you have your .fs and .fsproj files. Type the following command.

dotnet --version

If you have dotnet installed, you should see the version number. If not the dotnet command is not recognized. Make sure the version number 2.0 or above. If you do not have the right version download the .Net Core SDK from here.

Now make sure you are in your project folder. Run the following command

dotnet run

and wait for it.. and there you should be seeing Hello being printed on the console window. This command runs your code. And if you see Hello on the console window, then your code works well. Great!

Lets also build an executable.

dotnet build -r win-x64 -c Release

This command builds the project. There are two parameter options passed to the command. -r and -c. -r is for the runtime identifier, here its value is win-x64, because I am running it on windows. -c is for the configuration, here its value is Release. Other value for -c could be Debug. But we are ready with our application and no debugging is required, I chose release. When you have run this command you would see a hello.exe in the following path of your folder ../Hello\bin\Release\netcoreapp2.0\win-x64. Run the exe on the command prompt and you would see Hello. Congratulations you have built an F# application.

Until next time. Cheers.


Originally published at vijeshsalian.wordpress.com on June 15, 2018.