Cross-platform F# scripting

I love using Visual Studio Code (VSCode) as my main editor whenever I can, and because I’m an F# developer, I get to use the amazing Ionide plugin .

But to get specific, the main thing I use F# and VSCode for is F# scripting. F# scripts are the best tool for doing ad-hoc computing work, such as:

  • Trying out a library
  • Writing a utility to process some stuff, like transforming markdown files
  • Testing out someone’s code when they’re asking for help in the F# Slack , F# Forums , or pretty much anywhere
  • Etc.

Sometimes I’m on my windows desktop and sometimes I’m on my macbook. But none of that matters, because I can always script in the same way! Here’s the guide:

Setup

You just need three things:

  1. Visual Studio Code
  2. The latest .NET SDK (.NET 5 or higher)
  3. The Ionide plugin

Install all 3 and then you’re ready to go!

Opening up the right workspace

Visual Studio Code sets up a workspace with a folder. So you need to be inside a folder to be able to activate any plugins for files.

If you don’t have a good directory for scripts, I recommend setting up one. Mine is called scratch. I then open up VSCode from the command-line like so:

cd scratch
code .

And now it’s open in my scratch directory, like so:

My scratch directory
My scratch directory

Creating the F# script file

Now that I have a workspace open, I can just create a .fsx file.

I click the new file button at the top:

And name the file with .fsx as the extension:

Create a new F# script file
Create a new F# script file

And now it’s recognized as an F# script file:

opened F# script file
opened F# script file

Writing some code

Now I can write some F# code! Here’s a simple routine that turns a string into pig latin and calls it:

let vowels = set ['a'; 'A'; 'e'; 'E'; 'i'; 'I'; 'o'; 'O'; 'u'; 'U']

let toPigLatin (name: string) =
    let firstChar = name.[0]
    if vowels.Contains(firstChar) then
        $"{name}yay"
    else
        $"{name.[1..]}{firstChar}ay"

toPigLatin "phillip"
toPigLatin "apple"

It uses string interpolation to construct the strings (new since F# 5!).

Executing the script

Now that the code is written, it’s just a matter of executing it to get results. It’s easy!

Highlight all F# code you want to process in the editor, or just select everything like I do here:

Selected F# code
Selected F# code

And simply pretty the Alt+Enter key command on your keyboard. This will pop open the F# Interactive process window where you can see the whole script evaluated.

Let’s evaluate the toPigLatin "apple" call. To evaluate it, simply place your cursor on the line in code like so:

Evaluating the line
Evaluating the line

Now hit Alt+Enter on your keyboard again! This will only evaluate the current line. You can see in the integrated terminal now that the call was evaluated:

Evaluating "apple"
Evaluating "apple"

Tada! This is how you iteratively process F# scripts:

  1. Send code to interactive with Alt+Enter
  2. Write lines of code that call functions or methods or anything
  3. Send those lines via Alt+Enter on-demand to see results

Using packages

A super common thing people like to do is write F# scripts that use pacakges. This is trivial now with the #r "nuget" command. Here’s an F# script that uses JSON.NET:

#r "nuget: Newtonsoft.Json"

open Newtonsoft.Json

let record = {| Name = "Phillip"; Age = 30 |}

printfn $"{JsonConvert.SerializeObject(record)}"

Simply use this directive at the top of a script to reference any package. It may take a short time to get IntelliSense because the package may have to be downloaded from nuget.org, but once it’s done you’ll get IntelliSense for that package like so:

Package IntelliSense
Package IntelliSense

Tooltips, autocomplete, everything! Super convenient. And I can evaluate it just like the other script, too:

Evaluating some JSON code
Evaluating some JSON code

Bam! Super simple and productive.

Support F# in Visual Studio Code

F# tooling in VSCode is a daily driver for me. I get valuable work done for my employer in it. I create successful side projects in it. I maintain open source libraries with it.

Because of this, I personally support Ionide as a backer through the OpenCollective portal .

Are you working for a company that uses F# in any respect? Consider getting them to back Ionide. If that’s not possible, fork over 10 bucks a month. It’s not much, but with enough backers it allows for the maintainers to spend a lot more time on bug fixes, stability, and new features. Most backers are individuals, which means more people have to chip in to make it a more sustainable project … unless more organizations offer financial backing.

So write your next F# script with ionide and consider becoming a backer to keep the momentum going.