"I’d like to make a simple function that does some work in the background, and lets us know when it’s done by running another function with the results of said background work"
This is why he's got a problem, in a nutshell. I suspect the author has a heavy Javascript background and is used to Continuation Passing Style (CPS)[1]. The problem is that in a non-interpreted language that is a horrible way to do things because of scope and references. A better approach is to use messages from your thread. In C++ you could do this with ZeroMQ inproc sockets [2], or other mechanisms. In JAVA you could use a number of methods, such as a ConcurrentLinkedQueue [3]. In Go, you have channels [4]. In Rust, you have..well, also channels. Rust By Example already has a similar example that uses channels [5]. The concept of a Message Passing Interface (MPI) works amazingly well, and there is at least one flavor implemented for all the major languages (and often more).
The only languages I've seen that get callback style interfaces done well are Clojure, Lisp, Erlang, and Elixir.
The only thing I've seen that's better than MPI, in some situations, is Tuple Spaces [6].
Tar and feather me for it, but I miss JINI [7] and JavaSpaces [8] when I have to do a system in JAVA. JINI is now Apache River [9], but the last release was 2016.
This is why he's got a problem, in a nutshell. I suspect the author has a heavy Javascript background and is used to Continuation Passing Style (CPS)[1]. The problem is that in a non-interpreted language that is a horrible way to do things because of scope and references. A better approach is to use messages from your thread. In C++ you could do this with ZeroMQ inproc sockets [2], or other mechanisms. In JAVA you could use a number of methods, such as a ConcurrentLinkedQueue [3]. In Go, you have channels [4]. In Rust, you have..well, also channels. Rust By Example already has a similar example that uses channels [5]. The concept of a Message Passing Interface (MPI) works amazingly well, and there is at least one flavor implemented for all the major languages (and often more).
The only languages I've seen that get callback style interfaces done well are Clojure, Lisp, Erlang, and Elixir.
The only thing I've seen that's better than MPI, in some situations, is Tuple Spaces [6].
Tar and feather me for it, but I miss JINI [7] and JavaSpaces [8] when I have to do a system in JAVA. JINI is now Apache River [9], but the last release was 2016.
[1] https://en.wikipedia.org/wiki/Continuation-passing_style
[2] http://api.zeromq.org/2-1:zmq-inproc
[3] https://docs.oracle.com/javase/9/docs/api/java/util/concurre...
[4] https://gobyexample.com/channels
[5] https://doc.rust-lang.org/rust-by-example/std_misc/channels....
[6] https://software-carpentry.org/blog/2011/03/tuple-spaces-or-...
[7] https://en.wikipedia.org/wiki/Jini
[8]https://river.apache.org/release-doc/current/specs/html/js-s...
[9] https://river.apache.org/