5 ms·
Was reading docs on actors https://tutorial.ponylang.io/types/actors.html https://tutorial.ponylang.io/types/actors.html And I wonder what makes pony actors d
by nikivi 4y ago
Was reading docs on actors
https://tutorial.ponylang.io/types/actors.html https://tutorial.ponylang.io/types/actors.html
And I wonder what makes pony actors different to Go's goroutines?
- insanitybit 4y agoPony actors: 1. Have a typed, nominal interface (called behaviors) 2. Have state Those are probably the main differences, just with regards to actors.
- jerf 4y agoIn general, your latter question is better asked as "what makes actors different from threads?", because in practice a goroutine is just a thread. (What makes Go different from C++ in the 1990s is more community practice around what concurrency patterns are most commonly used, rather than technical differences in the language. Technically Go is just a mutable threaded language; for this purpose details about how the threading is accomplished are not that important.) In general the big difference with actors is that they are isolated from each other in some manner that means they can't just reach in to some other actor's memory space and manipulate the memory concurrently. Languages are starting to blur the lines here. Rust's lifetime annotation is not on its own sufficient to call Rust an "actor-based language" but the fact that they also prevent threads/async processes from just reaching in and manipulating other threads/async process's value unexpectedly means you've certainly taken a big step in that direction. And while Go provides no language-level technical support for actors, I still have a lot of things that are de facto actors in Go that uses scoping and export rules to confine the ability of other goroutines to interfere with a particular "actor"'s values, combined with an API that enforces message-based communication even though it works through what look like normal methods. This is not enforced at all technically by the language but it works better with community code than it does in older thread-based languages because the Go community is more recent and you can generally rely on libraries using somewhat more modern concurrency primitives, like providing services based on actors or actor-like objects. There are some things in programming where if you mostly follow some practice, you get most of the benefit. There are other things in programming where the benefit only kicks in if you do it almost entirely correctly; an example of the latter is Haskell's rigid insistence on functional programming and immutability, I'm not convinced that it's worth doing 90% of that but when you fully commit and build the language around it, there is an interesting spike in capability at the end. After programming in this space for well over a decade now, I kinda feel like actors are in the former case. I'm not sure you truly need a full language-level dedication to them to get most of their benefits. There is a last level of confidence and surety you can get in a language like Erlang, but I still think in practice that's just a last incremental benefit rather than a sudden burst in utility as you get to 100% purity. I think it's fine to program an actor here and an actor there in other languages and you get the benefits right there on the spot. Even what benefit there is, things like Rust gain in a different way. Still, I've been watching Pony with some interest.
- galaxyLogic 4y agoThe benefit would be if there was a language where everything is an actor. It would greatly simplify your programming model. I'm thinking of the early versions of Smalltalk which tilted towards this direction. Why did they abandon 'active objects'? I guess the hardware just wasn't there yet.
- zozbot234 4y agoRust effectively accomplishes this, because mutating a value that's accessible by a different thread requires both interior mutability and a separate Sync trait, meaning that accesses will be properly synchronized. Some types implement this (atomic types, Arc, Mutex, Rwlock) but the default is not to, so the default is that data may only be mutated by a single thread at any given time.
- galaxyLogic 4y agoI think there is more to Actors than just single-thread-access. Namely only the code of a given actor(-class) should be able to read and write the internal state of "instances" of that class. Why because then only the code-unit/module that defined the state variables can depends on their definition. A bit like "objects" internals can only be accessed by methods of its class.
- jerf 4y agoThere are languages where everything is an actor, like Erlang. I said what I said because I worked in them professionally for many years. While there is incremental benefit to being 100% actors versus 90% actors, I don't think it's that impressive of an incremental benefit, and is easily overwhelmed by many other factors. That's why I work mostly in Go and borrow actor structures when helpful. That turns out to be every non-trivial program I've written so far... but there's no particular benefit and often non-trivial costs in trying to write the whole program as actors, rather than using actors as useful servers. The simplification of being able to look at something and just know it's an actor I don't find very helpful. It's not hard to document these things, or see them in the structure of the code. By contrast, 90% pure functional programming is a pretty terrible paradigm. You really need to push that number up to get the benefits. As you approach 100% I think the benefit starts to take off. But, speaking very sloppily since "percent pure functional programming" is kind of difficult to precisely define, 90% is like the worst case scenario. 20%, which is to say mixing it in to other paradigms when useful without commitment and without paying much price and just harvesting the low hanging fruit can be very nice, and 99.9% can be very powerful, but 90% is the worst case, where you're paying most of the price but getting few of the benefits of true commitment. This is what I mean by seeing a lot of benefit in going the full way. I don't see this benefit to actors. They work just fine embedded into large programs and deliver the vast bulk of their benefit without having to structure the entire program around them. Definitely still worth learning; I consider them a core technique in concurrency programming. When you can easily afford the message marshaling and concurrency expenses, they are one of the easiest ways to get concurrency without complexity. And most of the time, you can afford those costs.