F # 1: Hello World

This text is a free translation of a series of Sacha Barber articles from Brighton, UK that I found interesting enough



This is the first post in my F # series. So what are we going to cover? As many programmers know well, it is customary to start with the Hello World example.



So we will do just that. So, without further ado, what you need to create a separate application "Hello World" in F #.



Here it is:



open System [<EntryPoint>] let main argv = printfn "Hello World" Console.ReadLine() |> ignore 0
      
      





// Unfortunately, I could not find the code allocation for F #



This may not seem enough to discuss, but there is already something to consider in order to immerse yourself in some of the principles of F #.



So what exactly is going on here?



Since this is a separate application, we obviously need an entry point (just like any other .NET language).



So how is the entry point determined?



Well, it's almost the same as with other .NET languages, we have a Main method (or a function in F # terminology) that takes a string array, and we use the [] attribute to indicate that the method with this attribute is entry point.



The compiler and Visual Studio love us for this.



Even in this example, you should hear alarm bells or at least some sense of misunderstanding. So, we said that there is an initial function that takes an array of string type. All I see is a variable named “argv”, which I do not see declared as an array. This “argv” variable is obviously the string array that we expect, but why it has no type .... MMM interesting.



F # has a very good type inference system, which means that in many cases you can omit the type at all, and F # will correctly output it. Of course, you can still fully declare the type of the input variable if you want, where it usually takes the form



(variableName: variableType)



Therefore, taking the “argv” example above, we could instead declare the above program as follows, and that would be nice:



 open System [<EntryPoint>] let main (argv :string[]) = printfn "Hello World" Console.ReadLine() |> ignore 0
      
      





You see that we have completely defined the name of the input variable with its type, which in this case is an array of string [].



What else interests there? Well, as I said, there is something to talk about.



Why do I have a line with this strange |> ignore at the end. What is it?



Well, since this is a F # console application, I wanted the application to not shut down until the user enters a character. So I need to do 2 things:



  1. Open the "System" namespace, which allows me to use the "System" namespace types, much as if I were using "using System" in C # or "Imports System" in VB .NET. "
  2. Since F # is a functional language, it will complain if the function, in this case “Console.ReadLine (...)”, which can return a string, does not pass the result further to the “ignore” function, which actually means return () (this is the way in F # say void, but it's called Unit). This explicitly tells F # to ignore the result of calling the Console.ReadLine (..) method.


For example, here is what the code will look like if I decide not to include |> ignore



image



The C # / VB.NET programmer may not see what is being said here. But F # is pretty tough on what a function can and cannot do. And one thing that a function SHOULD ALWAYS do is return a result. In the case of the "main" function, the expected result will be an integer value of 0.



But what about the case of "Console.ReadLine (..)"?



Well, at least in this case, the result does not matter much, and we are not interested in it, and the program will still work fine if we skip |> ignore , but if you are really not interested in the result, you should learn to use |> ignore . Just in case you are interested, the pipeline operator "|>" will direct the return value of the left expression to the right function, which in this case is equal to "accept the return value of Console.Readline (...) and ignore how nobody cares about it . " Do not worry if this does not mean anything to you at this stage, we will talk more about this later.



The last thing I need to do is make sure that the F # function always returns a value, this is done in the line where you just see the line 0. This is enough for F # to understand that this is the return value “0”, which the type inference system will output this Int value of 0. The reason the F # compiler knows that this is a return value is because in this case it is the last statement, so it MUST be a return value. Obviously, this can be complicated by using conditional logic if, else, etc. It is important to note that in F # the function SHOULD ALWAYS return a value, and in this case, since the value 0 Int was the last string found (although everything could be more complicated), it is used as the return value. Of course, you can return Unit, which is done using "()", which actually returns nothing (void, if you want).



Another thing I would like to mention in this trivial example is that space plays a key role in the development of F #.



For example, suppose my trivial example looked like this in an editor (in my case, Visual Studio 2012):



image



This is a tiny program, and ALL I did was remove the spaces at the beginning of the printfn line. Mmmm, it looks like the F # compiler didn't like that at all. Yes, that’s fair.



In F #, a space is VERY VERY important, so play with it well, otherwise get used to debugging cryptic errors like the one shown above, which is caused by a simple problem of incorrect semantic space.



Anyway, this is an example of “Hello World”. Until we meet again next time, I wish you all the best.



All Articles