In F# interactive, how can I see a list of variables/functions defined in this session? Like a function whos()
in python or ls()
in R? Thanks.

- 7,972
- 3
- 38
- 61

- 103
- 1
- 4
3 Answers
You can probably implement this using .NET Reflection - local variables and functions are defined as static properties/methods of types in a single dynamic assembly. You can get that assembly by calling GetExecutingAssembly
(in FSI itself) and then browse the types to find all suitable properties.
The following is a reasonably working function for getting local variables:
open System.Reflection
open System.Collections.Generic
let getVariables() =
let types = Assembly.GetExecutingAssembly().GetTypes()
[ for t in types |> Seq.sortBy (fun t -> t.Name) do
if t.Name.StartsWith("FSI_") then
let flags = BindingFlags.Static ||| BindingFlags.NonPublic |||
BindingFlags.Public
for m in t.GetProperties(flags) do
yield m.Name, lazy m.GetValue(null, [||]) ] |> dict
Here is an example:
> let test1 = "Hello world";;
val test1 : string = "Hello world"
> let test2 = 42;;
val test2 : int = 42
> let vars = getVariables();;
val vars : System.Collections.Generic.IDictionary<string,Lazy<obj>>
> vars.["test1"].Value;;
val it : obj = "Hello world"
> vars.["test2"].Value;;
val it : obj = 42
The function returns "lazy" value back (because this was the simplest way to write it without reading values of all variables in advance which would be slow), so you need to use the Value
property. Also note that you get object
back - because there is no way the F# type system could know the type - you'll have to use it dynamically. You can get all names just by iterating over vars
...

- 240,744
- 19
- 378
- 553
-
when I run the cide above, I got a lot of `it` in vars: `Microsoft.FSharp.Collections.FSharpList`1[System.Reflection.PropertyInfo] it`, what's this and how to filter this out? thanks – user 9081 Feb 15 '11 at 14:10
-
Yes, "it" is automatically generated by F# Interactive (you can see that `it` is also printed in the output - and you can use that variable to get the last result). You can either filter them or just take the last one... – Tomas Petricek Feb 15 '11 at 15:09
-
Wow Thomas, you're a freaking genius. I'm learning F# from you and Jon's book by the way, and I love it :) Great work. Any plans for another book? If you do, stick with Manning, they're a great publisher (at least from my perspective). – Martin Doms Feb 15 '11 at 20:09
-
2Very useful, but it would be better to yeid `m.Name , (fun () -> m.GetValue(null, [||]))` instead of `m.Name, lazy m.GetValue(null, [||])`.. you’d replace `vars.[“test1”].Value` with `vars.[“test1”]()` and get support for mutable objects because the functor evaluates each time. – Steve Channell Feb 21 '12 at 12:28
-
@TomasPetricek This method seems to be not working with the latest (either FSharp.Compiler.Service or net6.0). Any ideas/suggestions? The method was effectively engaged for a while... – Roman Kuzmin Jul 17 '22 at 12:36
I'm developing FsEye, which uses a modified version of @Tomas' technique (filters out unit and function valued vars and only takes the latest it
var) to grab all FSI session variables upon each submission and displays them visually in a tree so that you can drill down into their object graphs.
You can see my modified version here.

- 22,107
- 9
- 81
- 136
-
haha I was thinking of doing something similar, looks like this is exactly what I was looking for! I'll give it a try, awesome work from the look of it! – gjvdkamp Aug 24 '11 at 17:06
-
Good to hear! It started off as just a little personal tool but then began coming together nicely and I realized a lot of other folks were probably looking for the same kind of thing so I polished it off and released it. – Stephen Swensen Aug 24 '11 at 18:25