function-pointer-madness

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
C
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;
C#
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;
C++
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;
Haskell
run
consume Haskell
sequence (for_each (lowercase_all [ABC, DEF]) consume)
Java
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;
JavaScript
const run = () => console.log(“Hello World!”);
const consume = text => console.log(`Hello ${text}!`)
const lowercaseAll = strings => strings.map(string => string.toLowerCase());
Python
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
Rust
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;

GitHub

View Github