Daniel
Daniel

Reputation: 6039

Entry point issue in F#

I have the following program :

let readStoriesInQAForm = 
    printfn "Inside the let!"
    0 

[<EntryPoint>]
let main argv = 
    printfn "Ah! entering point to the main!"
    System.Console.ReadKey() |> ignore
    0 // return an integer exit code

I was expecting to get the following output (since main is the entry point, and there is no function call):

Ah! entering point to the main!

But I get this, when I compiler and run it in VS 2013:

Inside the let!
Ah! entering point to the main!

What is my mistake?

Upvotes: 4

Views: 2908

Answers (3)

Mark Seemann
Mark Seemann

Reputation: 233150

As John Palmer describes in his answer, F# code is executed from top to bottom. The let keyword binds a value to a name - in this case, the value 0 is bound to the readStoriesInQAForm name.

Apart from primitive values, you can also bind functions to names; F# is a Functional programming language, so functions are values too. If you bind a function to a name, you can execute that function by invoking it.

However, readStoriesInQAForm isn't a function - it's a primitive value (0), and it gets bound before main is called, in order to make that value available for main. In this particular case, the way the let binding is defined, it has a side-effect of printing to Standard Out when the binding occurs. (In general, in Functional Programming, the more you can avoid side-effects, the better.)

If you want to avoid this behaviour, change the let binding from a a primitive value to a function:

let readStoriesInQAForm () = 
    printfn "Inside the let!"
    0

Better yet would be to bind the name to the value without any side-effect:

let readStoriesInQAForm = 0

Upvotes: 7

John Palmer
John Palmer

Reputation: 25516

In a F# program, the code is essentially run from top to bottom, so that any values needed later are available.

For example, if you had written:

[<EntryPoint>]
let main argv = 
    printfn "Ah! entering point to the main!"
    printfn readStoriesInQAForm
    System.Console.ReadKey() |> ignore
    0 // return an integer exit code

The observed behaviour makes perfect sense as it would be illogical to jump out of main to calculate a constant value.

To avoid this issue, you want to make readStoriesInQAForm a function, like so:

let readStoriesInQAForm() = ...

Upvotes: 6

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

You're not declaring a function, you're declaring a value. It's missing ():

let readStoriesInQAForm() = 

Upvotes: 5

Related Questions