Pony is one of the new languages that intrigue me the most. Its performance seems very good, but how would you compare its expressiveness to e.g. Python?
That's a tough one. Python's dynamic typing means that you can write concise code as long as everything is of the correct type. But the consequence of this is that it is easy to accidentally express the wrong thing and only find out about it at runtime.
Pony's type system requires that you be a bit more explicit, but the tradeoff is that you get better guarantees about the correctness of your program. As your program grows in size these guarantees become more and more useful, or at least that's what I've found.
One part about Pony that can seem like an impediment to expressiveness in Pony is reference capabilities. Pony forces you to think about how objects can be accessed from different actors, which can sometimes make it hard to do things that seem like they would be simple, especially if you are new to the language. The payoff for this is that once you get the reference capabilities correct the compiler guarantees that your program will not have race conditions. In some ways, I'd say that if you're writing multi-threaded code then expressiveness that doesn't offer any safety guarantees is a false economy, because you'll probably end up rewriting the "expressive" code many times to get things right.
Python's a great language, and I don't mean to disparage it. I've used it quite a bit in my career, and for certain types of problems it is still the first tool that I reach for. In my mind, Pony excels in some areas where Python is somewhat weak, so they can live comfortably together in your programming toolbox.
I have only played with Pony briefly, because library ecosystem is not there, yet, for me. But the type system, and especially the reference capability system was beautiful, once I had gotten over the first local maximum of the learning curve.
I have been spoiled by too many languages with rich standard libraries and third-party library ecosystems, but if Pony gets enough traction to catch up, it is a language I would absolutely love to use. Just think about it - you can have massive concurrency going on, with mutable state, and yet, if it compiles, all is well. It is too good to be true, yet it is here.
I'm a member of the Pony core team. Library and ecosystem definitely needs.. well, more. Lots more. That isn't going to happen without folks like you who like the language becoming part of the ecosystem and contributing. I encourage you to join in, we are happy to get more help!
> Pony forces you to think about how objects can be accessed from different actors, which can sometimes make it hard to do things that seem like they would be simple, especially if you are new to the language.
Can you write single-threaded code in Pony without doing this, or do you have to do it regardless? The former would seem like a form of premature optimization.
Pony is an actor based language. You have to have at least one actor. Effectively, the answer is no. You could write "single-threaded" Pony code but it's not something you would do.
Pony is designed to make something hard- writing efficient, safe, concurrent code- easy. Anything you make something that is hard easier, you are invariably going to make some other things less easy, perhaps even difficult.
You can mostly do this by making all of your objects "ref", meaning you can have multiple readers and writers but you can't share the objects between actors. However, you can run into multithreading quickly because so much of the system is built on top of actors. For example, you can have a mutable (ref) string, but you can't easily print it out because the stdout stream is managed by an actor and you can't send a ref object to another actor.
Once you get used to reference capabilities they aren't really a big deal, but it can be hard at first, especially if you aren't thinking about your program executing thing concurrently.
Even after years of programming, most people (myself included) still instinctively think of concurrently executing code as the exceptional case, rather than as the common case. Pony makes it easy to write concurrent programs, but it makes you be explicit about how to do it safely. So I guess I see it less as a premature optimization and more as a different way of thinking about problems.