Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I call a function by name in f#?

Tags:

f#

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.

like image 908
Johann Hibschman Avatar asked Feb 20 '14 13:02

Johann Hibschman


People also ask

How do you call a function from a name stored in a string python?

Use getattr() to call a class method by its name as a string Call getattr(object, name) using a method name in string form as name and its class as object . Assign the result to a variable, and use it to call the method with an instance of the class as an argument.

How do you call a function?

You call the function by typing its name and putting a value in parentheses. This value is sent to the function's parameter. e.g. We call the function firstFunction(“string as it's shown.”);

Can you use a string to call a function?

There are two methods to call a function from string stored in a variable. The first one is by using the window object method and the second one is by using eval() method.

How do you call the sum of a function name?

=SUM(number1, [number2], [number3]……) The SUM function uses the following arguments: Number1 (required argument) – This is the first item that we wish to sum. Number2 (required argument) – The second item that we wish to sum. Number3 (optional argument) – This is the third item that we wish to sum.


1 Answers

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"
like image 170
Tomas Petricek Avatar answered Oct 03 '22 23:10

Tomas Petricek