Can I call a function by name in f#?

f#

Solution

There is no built-in function for this, but you can implement it using .NET reflection. The idea is to search through all types available in the current assembly (this is where the current code is compiled) and dynamically invoke the method with the matching name. If you had this in a module, you'd have to check the type name too.

// Some sample functions that we might want to call
let hello() = 
  printfn "Hello world"

let bye() = 
  printfn "Bye"

// Loader script that calls function by name
open System
open System.Reflection

let callFunction name = 
  let asm = Assembly.GetExecutingAssembly()
  for t in asm.GetTypes() do
    for m in t.GetMethods() do
      if m.IsStatic && m.Name = name then 
        m.Invoke(null, [||]) |> ignore

// Use the first command line argument (after -- in the fsi call below)
callFunction fsi.CommandLineArgs.[1]

This runs hello world when called by:

fsi --use:C:\temp\test.fsx --exec -- "hello"

Problem

Is there any way to call a function by name in F#? Given a string, I want to pluck a function value from the global namespace (or, in general, a given module), and call it. I know the type of the function already. Why would I want to do this? I'm trying to work around fsi not having an --eval option. I have a script file that defines many int->() functions, and I want to execute one of them. Like so: ``` fsianycpu --use:script_with_many_funcs.fsx --eval "analyzeDataSet 1" ``` My thought was to write a trampoline script, like: ``` fsianycpu --use:script_with_many_funcs.fsx trampoline.fsx analyzeDataSet 1 ``` In order to write "trampoline.fsx", I'd need to look up the function by name.

Original source