How to write function pointer definitions in multiple languages.

In this repo the same functionality is presented in a variety of languages. This includes function pointers to

  • A simple function run that takes no arguments and prints Hello World!
  • A function consume that takes an argument to use as Hello {}!
  • A function lowercase_all that takes an array of strings and returns a new array with these strings converted as lowercase
  • A function for_each that applies another function (given by pointer itself) to an array of strings

Yes, a lot of languages have var/let/auto to deduce types. This overview is meant to present the differences in usage though, which often includes writing out the type signatures for use in fields or arguments.

Language Source example
void (*run)(void) = run_fn;
void (*consume)(const char *) = consume_fn;
char **(*lowercase_all)(const char *[], size_t) = lowercase_all_fn;
void (*for_each)(void *[], int, void (*)(void *)) = for_each_fn;
Action run = () => Console.WriteLine(Hello World);
Action<string> consume = static (text) => Console.WriteLine($”Hello {text}!);
Func<string[], string[]> lowercaseAll = static strings => strings.Select(static text => text.ToLower()).ToArray();
delegate*<IEnumerable<string>, Action<string>, void> forEach = &ForEach;
void (*run)() = run_fn;
void (*consume)(std::string &) = consume_fn;
std::vector<std::string> (*lowercase_all)(std::vector<std::string>) = lowercase_all_fn;
void (*for_each)(std::vector<T>, void (*)(T &)) = for_each_fn;
consume Haskell
sequence (for_each (lowercase_all [ABC, DEF]) consume)
Runnable run = () -> System.out.println(“Hello World”);
Consumer<String> consume = text -> System.out.println(“Hello “ + text + “!”);
Function<String[], String[]> lowercaseAll = Main::lowercaseAllFn;
BiConsumer<String[], Consumer<String>> forEach = Main::forEachFn;
// Alternative, to keep generic method – create and use separate interface:
ForEachInterface forEach2 = Main::forEachFn;
const run = () => console.log(“Hello World!”);
const consume = text => console.log(`Hello ${text}!`)
const lowercaseAll = strings => => string.toLowerCase());
run: Callable[[], None] = lambda: print(“Hello World!”)
consume: Callable[[str], None] = lambda text: print(f”Hello {text}!”)
lowercase_all: Callable[[List[str]], str] = lambda strings: map(str.lower, strings)
for_each: Callable[[List[str], Callable[[str], None]], None] = for_each_fn
let run: fn() > () = || println!(“Hello World”);
let consume: fn(&String) > () = |text| println!(“Hello {}!”, text);
let lowercase_all: fn(Vec<&str>) > Vec<String> = lowercase_all_fn;
let for_each: fn(Vec<String>, fn(&String)) > () = for_each_fn;


View Github