Three peculiarities of the Pony language

More than a year ago, I stumbled upon the Pony language and, as I wanted to try it out in real, submitted a pull request to make it work on DragonFly. Pony distinguishes itself from most other languages by using the actor model for concurrency. Furthermore, it has a very strong type system, which ensures at compile-time, among other things, that no data-races or deadlocks can happen at run-time. The concept of capabilities in Pony is somewhat similar to what we call ownership, borrowing, and aliasing in Rust, just that it seems to be even more advanced in Pony, but also more complex to understand. For instance, take a look at the documentation of Capability Subtyping or the section about Viewpoint adaption. Do you see what I mean?

In the following sections, I want to highlight two syntactical and one semantical peculiarity of Pony, which I have not seen in any other language so far.

No operator precedence

Most languages use the mathematical precedence rules we know from school:

1 + 2 * 3 == 1 + (2 * 3) == 7

Not so in Pony. It has no precedence rules at all! And I think this is a great feature, as this is a potential source of bugs. Instead, if there is ambiguity, you have to use parens, as I try to always do in my programs.

No shadowing of variables

Shadowing of variables is a doubtful feature found in many languages, for instance in C:

int i = 3;
for (int i = 0; i < 10; ++i) {
   // the outer `i` is shadowed here
}

A problem arises when you move the second variable declaration of i around. In Pony, shadowing of variables is strictly forbidden. Again, I think, this is a great feature, every other language should adopt, not just as a warning! In my hence opinion, programs like the one above are just bad style, hard to read, hard to understand, and just prone to errors.

Divide by zero semantics

In most languages, division by zero triggers a “division by zero” exception in the CPU, or, when using floating point arithmetics, results in Infinity. Not so in Pony, where integer division by zero results in 0. This decision avoids the need of an error result type for the division operator, as otherwise, Pony could not guarantee crash-safety any longer. This is a pragmatic choice, as any code that uses division no longer needs to handle these errors.