4 ms·
Yes, Actor is used in the technical sense axiomatized up to a unique isomorphism in the linked article and not in the common usage of a thespian ;-) Erlang not
by ProfHewitt 7y ago
Yes, Actor is used in the technical sense axiomatized up to a unique isomorphism in the linked article and not in the common usage of a thespian ;-)
Erlang not being able to directly express Actor behavior change means that Erlang programs are more obscure and convoluted.
For example, consider the following program:
ProcessorController[pk:PublicKey] *implements* controller
// initialize processor controller with a public key pk
currrentVersion ≔ 1 // processor current version number is initially 1
running ← Crowd [1] // running is a crowd of at most 1 running activities
boot[*itemIs* i *whichIs* Package[*imageIS* code, *versionIs* packageVersion],
signedIs s] ↦ // received boot request with item i and signed s
*IsEmpty* running *cases* // Check if the processor is running
True ⇾ // If not running, then
SigningChecker.[*itemIs* i, *signedIs* s, *publicKeyIs* pk] *cases*
// check that i was signed by s with private key for pk
True ⇾ // If signing check succeeds, then
currentVersion⩽packageVersion *cases*
// check processor current version is
// less or equal than package version
True ⇾ // If version check succeeds, then
(currentVersion ≔ packageVersion; // first update current version number,
code.run thru running)
// afterward run code in a hole of mutual exclusion passing
// thru running then returning a termination report
False ⇾ // If version check fails,
*Throw* BadVersionException[] // throw bad version exception
False ⇾ *Throw* BadSignatureException[] // If signature check fails,
False ⇾ // If already running, then
*Throw* AlreadyRunningException[] // throw already running exception
shutDown ↦ // received shut down request
*IsEmpty* running *cases* // Check if the processor is running
True ⇾ // If not running, then
*Throw* NotRunningException[] //throw not running exception
False ⇾ // If already running, then
*Cancel* running // cancel running returning Void
The challenge in Erlang is to implement the hole in the region of mutual exclusion in the above implementation.
- gmfawcett 7y agoHah, of course I meant the "techie" colloquial of Actor, not the thepsian one. But I suppose that my comment is true in both senses. :) Thanks for clarifying. I'm not familiar with your theory, but at least I understand why you raised the point -- some Erlang programs are needlessly complicated due to the language's (colloquial!) actor semantics.
- ProfHewitt 7y agoYou are very welcome gmfawcett! What Erlang programs have you found to be needlessly complicated?
- dnautics 7y ago> Some Erlang programs are needlessly complicated due to the language's (colloquial!) actor semantics. Maybe you're referring to junior-to-BEAM programmers reaching to prove they can use gen_servers everywhere? There are also obscure corners of OTP that are a bit of a mess, but I'd say that's because it's inherited a lot of C-style folkways and doesn't have hierarchical module aliasing in the same way that say Elixir has. And there's a substantial amount of using modules-like-factories that got picked up in certain corners of the ecosystem, probably from Java habits, but I don't see that as much in Elixir, which suggests that it's not the actor semantics so much as, just outdated programming trends that have accumulated in the erlang ecosystem by virtue of it being older, and a "less popular" language that other people try to shove their round pegs into (arguably elixir is the latest iteration of that but they seem to have made some really good choices, at least in my opinion).
- toast0 7y agoHow about something like this? I don't understand the code you wrote exactly, and I smooshed the processor into the controller, because it simplifies things. fun Self (PublicKey) -> CurrentVersion = 1, receive {upgrade, Function, Version, Signature} -> case sign_checker(PublicKey, Function, Version, Signature) of true when Version > CurrentVersion -> Function(PublicKey); true -> throw(bad_version); false -> throw(bad_signature) end; shutdown -> ok; _Other -> % here's where you handle work % But I don't know what work you wanted to do, % so I'm just looping Self(PublicKey) end end. You probably don't actually want to throw for these errors (why should the server stop if it got an invalid request?), and you probably want your messages to include a reply tag, so you can get the results (like gen_server:gen_call/2,3 does), but you know, examples on the interwebs; don't run them as-is.