1. 17

  2. 4

    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.

    1. 3
      1. 2

        I’m curious about how pony manage a runtime. The documents still empty: Memory Allocation & Garbage collection.

        1. 2

          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.

        2. 2

          Anyone able to speak to pony versus erlang/otp?

          1. 16

            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.

            1. 2

              Could you compare Pony vs Alice ?

              1. 4

                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:

                • Blocking operations - via futures and promises. So spawning an operation in a thread in Alice ML returns a future containing the value returned by the operation. If the operation has not yet finished in the thread then any other thread attempting to use that value will block until it is available. Code tends to look quite imperative and easy to follow. There’s no need to break up async operations into requests and replies or use callbacks.
                • Constraint programming built in.
                • Optional lazy evaluation.
                • The ability to serialize and deserialize language constructs. You can serialize entire modules, containing functions, and deserialize them on other machines and architectures. The component system of Alice is based on this.
                • Distributed functionality.

                Some things that Alice lacks compared to Pony:

                • Pony compiles to native code via LLVM. Alice uses a bytecode interpreter with a JIT based on GNU Lightning.
                • Pony’s garbage collection system is more advanced with per actor heaps and the ability to GC actors that cannot receive messages anymore. Alice uses a simple stop the world mark and sweep IIRC.
                • Pony has an easy to use FFI allowing calling C code and having C code call Pony code with in-language declarations. Alice requires interacting with the Seam VM in C++ and implementing wrappers. These are compiled to shared libraries that can then be loaded from Alice.
                • Pony is multicore - actor behaviours are run on available cores and uses a work stealing scheduler (I believe). Alice is single threaded with multiple green threads run within a scheduler in that single thread. The Seam VM is not multicore.
                • Pony has the capability system and the ability to have compile time prevention of deadlocks. You can see some examples on the Alice ML mailing list of implementations of channels and other things where subtle data races and deadlocks occur if they are not well thought out - even when using Alice ML features.

                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.

                1. 1

                  I’m not familiar with Alice

                  1. 2

                    Pony looks amazing. Do you think a transpiler from Erlang to Pony would be possible? Implement the Erlang runtime in Pony?

                    1. 6

                      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.

                2. 1

                  Thanks for the overview.

                  1. 3

                    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.


                3. 4

                  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.

                  1. 2

                    I bet @seantallen could give you a great overview.

                    1. 1

                      I probably could ;)