What is Pony?
You can think of Pony as a combination of Rust (a programming language designed for performance and safety, especially for safe concurrent and memory management) and Erlang (a programming language used to code WhatsApp). It has remarkable features:
Type-safe: Protected from type-related errors.
Memory-safe: Protected from various software errors and security vulnerabilities when accessing memory.
Exception-safe: The code remains in a working state even when exceptions are generated.
Data race-free: Avoids data race, a common issue in concurrent programming where multiple tasks access a shared resource without sufficient protection, leading to undefined or unpredictable behavior.
Deadlock-free: Prevents a situation where processes are blocked because each process waits for another resource to execute.
Additionally, Pony is compiled from its own code and is offered under a BSD license with two clauses.
Why Pony?
Writing fast, safe, efficient, concurrent programs is not easy with most existing tools. “Fast, efficient, and highly concurrent” is an achievable goal, but add “safe,” and things become much harder. This is where Pony comes in and makes this task easily achievable.
Concurrent Programming
Pony simplifies concurrent programming (the simultaneous execution of multiple processes over a period of time). One way it achieves this is by providing a strong opinionated concurrency story. In Pony, all concurrency is achieved through the actor model.
The actor model is most famously implemented in Erlang and Akka. The actor model has been around since the 1970s, and the details vary significantly from implementation to implementation. What remains consistent is that all computations are performed by participants communicating via asynchronous messages.
Think of the actor model this way: objects in object-oriented programming are state + synchronous methods, while actors are state + asynchronous methods.
When an actor receives a message, it executes the corresponding method. This method can operate on state that is only accessible to that actor. The actor model allows us to use mutable state in a concurrency-safe manner. Each actor is single-threaded. Two methods within an actor never execute simultaneously. This means that within a given actor, data updates cannot cause data races or other issues typically associated with threads and mutable state.
Fast and Efficient
Pony “actors” are scheduled with an efficient work-stealing scheduler. There is one Pony scheduler per available processor. Threads refer to the highest level of code executed by the processor, so with many threads, your processor can handle multiple tasks concurrently. The thread-per-core model is part of Pony’s attempt to collaborate with the processor to work as efficiently as possible. Pony’s execution time aims to be as cache-friendly as possible. The less your code breaks the processor’s cache, the better it will perform. Pony aims to help your code work well with the processor’s cache.
In programming, garbage collection is a form of automatic memory management. A special process called the garbage collector periodically frees memory by removing objects that are no longer in use by the application. Stop-the-world is a crucial phase in some garbage collection algorithms for tracking memory. It halts program execution to scan roots of memory and add write barriers.
Pony’s execution time includes a heap per actor, so there’s no “stop-the-world” step during garbage collection.
This means that your program is always doing some work. As a result, Pony programs end up with much more consistent performance and predictable latencies.
Safe
Pony’s type system introduces a new concept: reference capabilities, making data safety part of the type system. The type system assigns a property, called a type, to each “term” (word, phrase, or other set of symbols). The type of each variable in Pony includes information about how the data can be shared among participants. The Pony compiler uses this information to check during compilation whether your code is protected from data races and deadlocks.
If this sounds a bit like Rust, it’s no coincidence. Pony’s capabilities and Rust’s Borrow Checker tool provide data safety; they just approach it in different ways and have different trade-offs.
Is Pony right for you?
Deciding whether to use a new programming language is difficult. You need to weigh the appropriateness of the tool against its immaturity compared to other solutions. So, what is Pony suitable for?
Pony might be the right solution if you need to solve a challenging problem with concurrent task execution in coding. Concurrent programming is the reason Pony exists. If you can achieve what you want in a single-threaded Python script, you probably don’t need Pony. If you have a problem with concurrent programming, you should consider Pony and its powerful type system protected from data races.
With this programming language, you’ll get a compiler that prevents you from introducing concurrency-related errors and execution time, giving you excellent performance results.