Congrats on the release. As someone whose day job is elixir but whose side project passion right now is rust, a high performance, strongly typed, actor model language like Pony is right up my alley.
My one hang up right now is the other half of the elixir magic: OTP. In particular supervision trees and genservers.
While Pony has an actor model and message passing for concurrency, I wasn't able to find anything OTP-like. What's more, I read some things that it was even impossible to express in the language since there's no mechanism to block and wait for a message. Is this true? Are there any plans down the line for support of this?
There are no block and wait patterns. That is true.
You need to structure you app as an async one. All communication between actors is async. This has the nice side-effect of making it really hard to write in a deadlock.
There are no plans to and wait at this time. It's not something that folks who are using Pony call for. It is something that folks coming from Erlang/Elixir want to see.
Perhaps they end up dropping off and we end up with confirmation bias that our approach is right. Perhaps we are on to something.
OTP wise, more patterns built into a library would be awesome and anyone who wants to take that one, we'd be happy to help support their effort.
As far as I know Pony doesn't yet have a distribution story so supervision might not be priority for the maintainers yet. However, since Pony is an "Active Objects"-language, every actor in Pony is essentially an instance of a genserver - this is what makes it easy to type. Supporting more advanced communication patterns in a strongly typed fashion is rather difficult so for the foreseeable future I believe that a gradual typing approach will be the way to go. Genserver is also very powerful so Pony can likely see good success if they just build in some supervision strategies and make it possible to distribute.
This is true. There is no distributed Pony at this point. It was a high priority early on but when we looked at everything we thought we needed for a 1.0 release, it didn't make the list.
And Sylvan and I spent a good amount of time discussing how to implement. Then a lot was learned while building Wallaroo over at Wallaroo Labs, we'd certainly lean on stuff from there as well.
If anyone is interesting in working on distributed Pony, we'd be happy to help support you. Come by the IRC or developer mailing list. Let's chat.
But, its not something that anyone is working on right now.
I hear a lot of hype about supervisor trees from Erlang folks, but very little description about what they do or why they’re useful. Are they applicable to other languages? Could someone point me to a good resource for someone who doesn’t know Erlang or Elixir?
Yes. The concepts are applicable basically everywhere. For example: do you know how systemd restarts your service if it crashes? How about how k8s behaves when your health probes fail?
It’s everywhere. Build it to crash fast if it has a problem. Have a higher level entity that monitors it and automatically restarts it/does something when it does crash.
Now go meta and have supervisors watching supervisors and controllably crash or restart bigger parts of your system. (This is based on the “crash early”, “keep state consistent”, “have you tried turning it off and on” principles. It’s not new and you’re probably already doing it tona certain degree)
It is basically "whatever thing in your system has an external dependency that's not 100% reliable, isolate it in an actor/process that can crash and be safely restarted".
Expand the concept to trees of dependencies and several possible after-crash strategies and you get very resillient apps.
But to fully appreciate it, you have to try it. It sounds pretty generic when advocated for but when you code a bit around that, it gets pretty amazing.
They are very useful if you follow the philosophy of Erlang: let it crash. It's really important to get easy to understand distributed systems. A good introduction: https://learnyousomeerlang.com/supervisors
I really like this description[0]. It's broadly about designing programs, and handling robustness and state, so I imagine it would apply to other languages, although it does mention some erlang specific things.
O my! Hi Pony core contributor here. Normally when I submit releases to HN, they kind of silently die. I was surprised to come back and see this on the front page. I'll check the comments from time to time and try to answer questions.
While I have your attention:
Pony is an all volunteer project. We could really use your support. We'd love to get more contributors of all stripes.
Code, documentation, design work. All of it! Come by the developer mailing list (https://pony.groups.io/g/dev) or #ponylang channel on Freenode and we'll get you started.
What lang ecosystem with an interactive REPL do you see as the best fit for pairing with and driving Pony?
I've been dreaming of ways to help bootstrap the Pony lang/lib interop story and build toward a numerical interactive programming environment, being able to combine Pony's native async Actor model and runtime safety guarantees, while also safely being able to hook into to an external ecosystems existing numerical computing, data structure, and GPU/TPU accelerator libs.
I seem to remember someone giving a lang talk a while back where in the Q&A the speaker said integrating with Pony might be a good fit. I was looking into dependent types at the time...it may have been Idris or OCaml, and hooking into the Julia ecosystem would be most interesting, with maybe even Zig acting like low-level LLVM glue code binding all the external C libs together.
In my dream I have it all and the Pony too! All the lang libs are hooked together in a typed-provable way, and when fully connected they combine to form a high-performance, interactive parallel distributed programming environment, and it runs in the browser too. What do you think, is that too much of a DeepDream?
Ideally something with a C-FFI interface and a runtime without a lot of concurrency opinions.
Hooking up Python and Pony is fairly straightforward for example. We've done it at Wallaroo Labs. That's very much "embedded a Python interpreter inside a Pony process" approach. Perhaps you are thinking of something different?
I'm not really sure what you are thinking of. If you sent your ideas to the user mailing list, someone might have some ideas. Something a bit more concrete might help on that front.
I haven't touched Pony in a while but it holds a lot of promise.
My paper cuts with Pony were:
a) No assertions/ unhandled exceptions. I believe things like divide by zero or any other case where you want an assertion should exist.
The actor model makes this easy, in theory. Actors are boundaries so just unwind to the actor boundary on exception and have your actor handle the failure from there. Sort of a 'catch all'.
My expectation is this is already how a ton of errors get handled in pony - bubble up to actor, handle. A pony dev can correct me here if that's not the case.
b) The conversions between types needs sugar. I remember some 'recover' statements that were really boilerplatey.
Maybe this is also an issue of compiler errors, if they'd guided me. But sugar around this would be nice as well.
All exceptions have to be handled, but they don't have to be handled at the call site, you can have them propogate back up if you want.
When you say assertion, do you mean, that you want to program to exit? If yes, that's fairly easy to do. We have several different variations of that in the Wallaroo code base.
Speaking as a Pony core member, I'd be open to adding a primitive to exit the program with an error message to the standard library. We have an RFC process for that: https://github.com/ponylang/rfcs/
And there are several examples from Wallaroo of that here:
> All exceptions have to be handled, but they don't have to be handled at the call site, you can have them propogate back up if you want.
Implicitly?
> When you say assertion, do you mean, that you want to program to exit?
No, I mean that in some cases I know better than the compiler. For example, in a case where something is T or None, but I know it's T. If T is None, it's a bug - but I don't want my whole program to crash. Ideally it would propagate up to some boundary where there's little enough shared state (the actor boundary) that I can restart my process without having to go through the whole program being restarted.
Otherwise my actor boundary becomes the entire process, and I feel like that sort of defeats the purpose of having extremely cheap, efficient actors.
So definitely not a 'kill the program' but a 'this feature has a bug, wind up the actor and restart it, but no other actors should blow up unless this is a direct dependency of theres'.
Basically the way Erlang does it afaik
I say this as an outsider. What you have may work for you, and maybe it's the right decision. That was just my impression as someone trying to use the language.
Will propagate the error you can get from y being 0.
The ? in the return signature is required to indicate that an error can happen.
- Re: assertions. We'll you can certainly do what you want when you know that haveing None from T or None is a bug. There is no "crash the actor" and start over in Pony. But it would be interesting to see what people came up with for patterns to "reset actor state"
There was a year of full time development when Casualty existed as a company to support Pony. That got Pony to the starting line. Since then its been a volunteer effort. A lot of people have contributed many great improvements.
If we had lots of paid folks working full time, we'd be further along.
What is the effort? A lot. Not trying to be pithy, but it really is a lot of work.
We'd love to have more volunteers to help out. And for folks who can't contribute time, we've started accepting donations so we can pay for hosting and other costs: https://opencollective.com/ponyc
Additionally, one of the language designers, Sylvan Clebsch, now works at Microsoft Research, so in a way Microsoft is also sponsoring the work on Pony.
I'm the VP of Engineering at Wallaroo Labs. Pony existed prior to Wallaroo Labs using it, but we have been very instrumental in pushing the language and runtime forward. We've contributed a lot of code to Pony.
If you are interested in the early history of Pony you can learn more from Sylvan's post here:
The GitHub contribution graph can be deceptive. The stuff Sylvan is working on these days tends to be deeper things that take a long time to get correct and often is a small amount of code.
He definitely isn't churning out tons of code for Pony these days. He is still, however, actively involved. From time to time, big new things from him show up. The latest one has been cooking for several months now and probably won't show up for a few more.
My one hang up right now is the other half of the elixir magic: OTP. In particular supervision trees and genservers.
While Pony has an actor model and message passing for concurrency, I wasn't able to find anything OTP-like. What's more, I read some things that it was even impossible to express in the language since there's no mechanism to block and wait for a message. Is this true? Are there any plans down the line for support of this?