Learning F# — Part 8 — dotnet
Last time we created a F# project manually. View that post here. This helps in understanding how projects work. But if you have to do that every time, it becomes very boring. Lets delegate the creation of projects to the dotnet tool which we had previously used to run our project. Download the latest version of .NET core SDK from here. At the time of writing the version is 2.1.301.
Make sure you have the latest version of .NET core sdk before proceeding further. .NET core 2.1 is the most coolest version. But don’t take my word for it. Read more here if you would like to.
Alright, now that you are all set, go to a freshly created folder. Give that folder a name of you choice. I am naming mine ‘Launch’. Learn to create folders on the command line/ the terminal. This will make you faster. If you do not know the commands to create a new folder on the terminal, then remember that search engines are your friends.
A file is made up of code
A project is made up of files
A solution is made up of projects
In most cases than not, the code is organized in multiple projects. This way related code exist in a project of its own and the code which has a different purpose can be in a different project. This is called separation of concerns. Even if you are a new programmer it is good to think in those lines of important principles. The Wikipedia page about Separation of Concerns is here.
A solution is top-level in the hierarchy of code organisation. The following command creates a solution. Navigate to the previously created folder in your command line. Lets go ahead and create a solution named ‘Launch’
dotnet new sln --name Launch
Note that if you do not give it a name, dotnet will create a solution with the name same as the folder.
Create a new console F# project. Remember that .NET supports other languages too. And projects are associated with the language its files are written with. So we would have mention the language as well
dotnet new console --name launcher -lang F#
In the above command, we sent in 2 arguments. name and lang. The arguments are identified by the double hyphen. Note that if you use a short name for the argument name then you use a single hyphen. Every argument name is given a value in the above command. name argument is given the value launcher. So the console project is named launcher. The language argument is given the value F# for obvious reasons.
We created a countdown function in Learning F# — Part 7 — rec. Lets make that function part of a library. In .NET world its called a class library. Rin the following command to create a library.
dotnet new classlib --name countdown -lang F#
This will create a project for our countdown library. All our projects are now created. So my Launch folder looks like this
Now add those projects to the solution.
dotnet sln .\Launch.sln add .\launcher\launcher.fsproj .\countdown\countdown.fsproj
Let’s edit the fsharp files now. I am going to use the VS code editor. You can use your favorite editor. If you want intellisense/code-completion on your VS Code editor, then use the Ionide extension. Although the extension is not a must for this exercise.
In the countdown folder, rename the file Library.fs to Counter.fs. Remember to change the name in countdown.fsproj too.
You will here notice in the file that there is a namespace declaration and a module as well. Like we saw earlier F# program can be physically grouped into solutions/projects/files. namespaces and modules are a logical grouping for F# code. Simply speaking, namespace is made up of modules. modules is made up values. namespace and modules can also contain types. But, we haven’t discussed types yet, so let’s take it up at a later point in time. It is enough to understand the namespace and module is for logical grouping of code. Read more about it at here and here.
My Counter.fs file has following code. The function may be familiar to you from the last part in the blog series. Note that here I do not use the namespace grouping.
let rec countDown x =
if x<=0 then 0
printf "%d\n" (x)
Now, we want the launcher project to use the countdown project. That means the launcher proj needs to reference the countdown proj. Here’s how you do it: It adds a reference of countdown proj to the launcher proj.
dotnet add .\launcher\launcher.fsproj reference .\countdown\countdown.fsproj
Now edit the Program.fs. The launcher proj is your main project because it has the entry point.
let main argv =
let countedDownTo = (countDown 10)
printf "T minus %d. Lift off!" countedDownTo
In the command line navigate to the folder containing launcher.fsproj and run the application using the following command.
You should be seeing the following result
T minus 0. Lift off!
Until next time. Cheers.