As most of you know, I am a C# kind of guy. So whenever I want to do a bit of mucking about where I just want to try something out, I will typically just spin up an instance of LINQPad and try stuff out in there. If things grow too much and I need more control over the experimenting, I will abandon LINQPad and will spin up a ConsoleApplication
in Visual Studio. Both of these approaches do work fine, but wouldn’t it be nice if there was some sort of environment where you could try stuff out within Visual Studio itself, without even needing to create a new project of any kind.
Luckily, in F#, there is just that. There is an absolutely brilliant tool called the “F# interactive window” (FSI), which you can find by using Visual Studio (I am using VS 2012) like this:
So once you open the F# Interactive window, you should see something like this:
Now this may not look that grand yet, but this window allows you to do a great many things pretty easily. It can be used for rapid prototyping, and inspection purposes if you like.
So you can see that you have the prompt >
which is waiting for some input from you. So how do I give it some input?
Giving Input
All you need to do within the F# Interactive window to get some input accepted is to end your line with 2 semi colons “;;
”.
Some valid examples of valid input are shown below:
Declaring a function that will take a value and square it (note we did not specify the type of x
):
let squarer x = x * x;;
And now, let’s declare a variable that will hold the return value of calling the “squarer
” function. This is easily done as follows:
let squared = squarer 10;;
Viewing Data
Should we wish to view data, we can also evaluate things in a similar manner. So assuming we have just typed in the values above, we would have the following in scope:
- A squarer function
- An
Int
value bound the squared variable
So to evaluate one of these, say the “squared” variable, we can simply type something like this into the FSI prompt:
squared;;
What happens when we run that line in the FSI is that the value is printed to the FSI window, something like this:
val it : int = 100
Where it can be seen that the value is indeed 100
, which is the result of the earlier call to the “squarer
” function that was created in the FSI window.
A Word About Scope
One of the other key benefits of using the FSI window is to do with scope.
To understand what I mean by that, say we had typed this function into the FSI window:
let someMathsFunction x = x + x
let add2ToIt x = (someMathsFunction x) + 2
And then I evaluated the results by doing something like this in the FSI window:
add2ToIt 12;;
Where the result would be this:
val it : int = 26
All good so far. But let's say I then did this in the FSI window, where I changed the way the “someMathsFunction
” works, say I get it to triple the input instead
let someMathsFunction x = x * 3;;
And then I tried to evaluate the original add2ToIt
function, which should be doing something like this now:
let someMathsFunction x = x * 3;;
let add2ToIt x = (someMathsFunction x) + 2;;
Which when asked to evaluate (say with the number 12
), should yield the following result:
12 * 3 + 2 = 38
But instead, when I run things (not shown here as same output as previously seen), I still get the old result of 26
.
This is down to scope within the FSI. If we told the FSI that both the function that changed (“someMathsFunction
” in this case) and the one that make use of it (“add2ToIt
” in this case), should be defined and rebound using the let
keyword, we should get what we are after (i.e., the correct result of 38
).
This may sound complex, but what I mean is, if we run this in the FSI window instead:
let someMathsFunction x = x * 3;;
let add2ToIt x = (someMathsFunction x) + 2;;
and then we evaluate that as follows:
> add2ToIt 12;;
val it : int = 38
We now do indeed get what we asked for. Why is this happening? Why didn’t we get it before?
Well, it is to do with the bind
keyword in F#, and the fact that the bind
needs to be set to the new range. Don’t worry too much about this for now, we will get into this in subsequent posts. For now, it is probably enough to be aware of this feature.
Last Cool Thing Before We Depart
Before we finish up on this post, I just wanted to mention that you can also use the FSI window along with a F# script file, should you wish to try things out quickly.
Say I had a F# script file (FSX) with the following code in it:
open System
let squareRootMe x = System.Math.Sqrt(x)
And I wanted to try that out in the FSI, I can simply highlight the lines / section of the code, and choose to execute it in the FSI window.
It is then in scope within the FSI window. Which means I can use the function, as demonstrated here:
> let x = squareRootMe 144.0;;
val x : float = 12.0