I’ve been using Pony on and off for some small projects over the last couple of months. I find the language quite easy to pick up and read but still struggle a bit with working out what capabilities to use to get things to compile. I hit similar issues learning ATS, with dependent and linear types, so I’m hopeful things will click in time.
Another thing I hit is how to deal with what would normally be a blocking operation in other languages I use. For example, if I want to do task A, then make an HTTP request, then when that is done do task B with the results of that request. In Pony it would be do A, call an actor’s behaviour to do the HTTP request passing a callback back to A when it’s complete, handle the result in the callback, then do B. This is a consequence of the async, no blocking, model that Pony has - not dissimilar to Node JS programming (except concurrent). It can feel a bit like programming in CPS.
Pony doesn’t have a blocking receive which makes programming feel different from Erlang. Instead of doing a receive and pattern matching on a result you write a behaviour on an actor which takes arguments.
The Pony implementation is fast to compile and so are Pony programs. The system feels very lightweight. The FFI allows easy calling into C libraries, including the ability to pass callbacks back into Pony, and you can generate C libraries from Pony. These libraries can be linked into an existing C application. There’s a C API for the Pony runtime allowing you to convert C threads into Pony actors, control scheduling, etc.
Pony is not as low level as ATS or Rust, but lower level than Erlang, Python, and other higher level languages. It sits in an interesting middle ground.
I’m curious about how pony manage a runtime. The documents still empty: Memory Allocation & Garbage collection.
What in particular are you interested in? I could probably fill you in some. Probably as in, I’m still digging through all the code.
Anyone able to speak to pony versus erlang/otp?
Erlang. Rock solid. Mature as hell.
Pony. New Kid on the Block. Immature as hell.
Pony draws a lot of inspiration from Erlang and has drawn interest from Erlang fans.
Pony has a lot better performance than Erlang. It’s designed for correctness and speed.
Erlang has OTP and has taken care of a ton issues over the years.
Pony has a very small standard lib, its saving grace on the library front is excellent C FFI.
Pony has a great type system that helps you write safe concurrent code.
People like to compare it to Rust at times because of that.
Erlang has both concurrent and distributed version.
Pony only has concurrent at the moment although plans are in the works for distributed Pony.
Tons of people are running Erlang in production.
Pony not so much.
If you have particular questions, I’d suggest dropping by #ponylang on Freenode or checking out the mailing list.
Could you compare Pony vs Alice ?
I like Alice ML. I maintain a github repository to keep Alice ML building. Pony is entirely asynchronous. There are no blocking operations. Some features of Alice ML that Pony doesn’t have or is different from:
Some things that Alice lacks compared to Pony:
I would really like to see an Alice ML VM written in Pony that uses Pony to take advantage of it’s efficient runtime. That would make for an interesting project.
I’m not familiar with Alice
Pony looks amazing. Do you think a transpiler from Erlang to Pony would be possible? Implement the Erlang runtime in Pony?
This is a really interesting question! (Full disclosure: I’m the Pony language designer, so I have a bias).
Erlang uses immutable data types, and Pony can express those. Erlang has actors, and Pony can express those. Erlang is dynamically typed, but Pony is statically typed. However, using Hindley-Milner unification, it would be possible to generate Pony interfaces (i.e. structural types) that expressed the implicit dynamic typing constraints in an Erlang program. So far, so good.
However, there’s a core semantic difference, which is that Erlang allows a blocking receive that pattern matches on the queue. In contrast, in Pony, all actor behaviours are strictly asynchronous. This would make an Erlang to Pony transcoder tricky - not impossible, just tricky.
Implementing an Erlang runtime in Pony would be similarly tricky, but implementing an Erlang runtime using the Pony runtime (which is available as a C library) would be “relatively easy”, where “relatively easy” means quite hard indeed, but with straightforward semantics.
I think the core places where the Pony runtime would be useful to Erlang are in garbage collection of both data structures and actors themselves (unlike Erlang, which requires manually terminating actors, in Pony actors themselves are GC’d with a protocol that allows the runtime to cheaply determine when an actor has no pending messages and can never receive messages in the future) and in code execution (BEAM, while a very impressive VM, doesn’t excel at computational speed, whereas Pony is, surprisingly, a bit faster than C, due mostly to LLVM’s lovely fastcall calling convention, which allows for really good cross-procedure register colouring, plus Pony has aliasing information that’s more useful for optimisations than that available to C).
However, Erlang has things Pony doesn’t have (yet). Particularly for distributed computing (although that’s in the pipeline for Pony).
tl;dr: Pony has been heavily influenced by Erlang (along with other awesome languages, like OCaml, F#, E, AmbientTalk, Smalltalk/Newspeak, and many others), but they aren’t semantically equivalent.
Thanks for the overview.
There’s more insight into where Pony is trying to go at: https://github.com/CausalityLtd/ponyc/wiki/Philosophy
That pages covers general principles and a hierarchy of concerns for the language.
I’m happy to discuss more if you want.
By no means an expert, but the short version is that pony has the potential to be radically faster than erlang; has a relatively tiny/nonexistent library set; and is currently for the adventurous.
I bet @seantallen could give you a great overview.
I probably could ;)