You can find more information about erlang in this Ph.D Thesis (1), on page 86 is an example of a universal server, explained with detail.<p><a href="https://erlang.org/download/armstrong_thesis_2003.pdf" rel="nofollow">https://erlang.org/download/armstrong_thesis_2003.pdf</a>
Excuse my Erlang ignorance.<p>When he sends the "{become, F}" message, and F is a function pointer or closure, how is that dispatched across a network? Do the code definitions need to be present remotely too? If so, I'm not sure that quite qualifies as a "universal" server, only a server for locally defined functions. Still cool though.<p>BTW, I've used a similar technique to create a pool of worker goroutines in Golang. Had good performance from it too.
Here are a couple previous discussions (only linking ones with comments):<p><a href="https://news.ycombinator.com/item?id=12396420" rel="nofollow">https://news.ycombinator.com/item?id=12396420</a> (38 comments)<p><a href="https://news.ycombinator.com/item?id=8807660" rel="nofollow">https://news.ycombinator.com/item?id=8807660</a> (2 comments)
Unfortunately, Erlang does <i>not</i> directly implement Actor behavior change.<p>Consequently, Erlang cannot directly implement Actor behavior change. A factorial server is implemented below:<p><pre><code> FactorialServer[ ] *implements* ProcedureServer<[NaturalNumber], NaturalNumber>
[i] |-> // received message [i]
Factorial.[i] // return result of sending [i] to Factorial
</code></pre>
In order to implement Actor behavior change, Erlang must resort to using helper processes that trampoline back so that helper processes can return the desired change.<p>See the following for direct implementation of Actor behavior change:<p><pre><code> https://papers.ssrn.com/abstract=3418003
</code></pre>
PS. The type ProcedureServer above can be defined as follows:<p><pre><code> ProcedureServer<t1, t2> ≡ // Procedure server with parameters types t1 and t2 is defined to be
t1 -> t2 // type of procedure from t1 into t2</code></pre>