
Pony: Combining safe memory sharing with Erlang-like actors - samuell
https://tutorial.ponylang.org/getting-started/how-it-works.html
======
spooneybarger
Pony core team member here.

We love when folks notice us, hopefully a couple people who read this end up
in the Pony community. That said, the "better-than-Rust" makes me
uncomfortable. Pony and Rust have different goals and make different tradeoffs
with regard to memory safety. We don't think one is better than the other.
They are different.

Anyway, back to my Sunday. Y'all enjoy.

~~~
GolDDranks
I just had a thought that made me ridiculously excited. Like in Pony, doing
FFI in Rust is unsafe for obvious reasons. But would it be possible to define
a subset of the typesystems of both languages to have a possibility of calling
Rust code safely from Pony? (I doubt it would work another way around, since
Pony needs its runtime.) That would create super cool synergy with ergonomic
and ultra safe Pony and ultra performant and safe Rust.

~~~
spooneybarger
I suppose it would be possible although I'm not sure it would be worth the
effort. Only one way to find out though.

------
spooneybarger
Pony core team member here.

Given this is a link to part of the tutorial. I'll drop some additional links
if you are interested in learning more:

high-level overview of Pony's value proposition:
[https://www.ponylang.org/discover/](https://www.ponylang.org/discover/)

our current "start here" resources for learning pony:
[https://www.ponylang.org/learn/](https://www.ponylang.org/learn/)

collection of blog posts, videos and what not:
[https://www.ponylang.org/community/planet-
pony/](https://www.ponylang.org/community/planet-pony/)

main compiler GitHub repo:
[https://github.com/ponylang/ponyc](https://github.com/ponylang/ponyc)

user mailing list you can sign up for to get more info:
[https://pony.groups.io/g/user](https://pony.groups.io/g/user)

#ponylang on freenode for IRC (generally very quiet on weekends)

~~~
Klasiaster
What about (multiparty) session types? Can they be implemented for the actors
to force them to follow a protocol?

~~~
sitkack
A Gentle Introduction to Multiparty Asynchronous Session Types [1]

[1]
[http://www.di.unito.it/~dezani/papers/cdpy15.pdf](http://www.di.unito.it/~dezani/papers/cdpy15.pdf)

------
humanrebar
Rust is designed to be a systems programming language in that it does not ship
with a garbage collector. Pony does have a garbage collector. Comparing their
memory safety is comparing very different categories of languages.

It would be better to compare pony's memory safety to a GC language: go, Java,
C#, Haskell, etc.

~~~
pjmlp
In what category would you put Oberon, Modula-3, Sing#, System C#?

~~~
coldtea
The first three surely in the "nobody uses and don't see that changing anytime
soon" category (haven't heard of the last one, special systems-programming C#
edition?)

~~~
pjmlp
The C# dialect used in Midori.

As for the rest, IT world is full of political murders of nice technology.

As Alan Kay puts it, pop culture driven development.

~~~
jonaf
Please tell me that the referenced C# dialect used in Midori is available in
some form for use, research or general learning? This would really make my
week!!

~~~
pjmlp
Just scattered information.

You have Joe Duffy's blog entries about Midori and one entry back when it was
still called M#.

Then there are the little pieces that came to C# from it.

Namely async/await, TPL, the MDIL compiler on Windows 8.x, the .NET Native
compiler for UWP, the improved GC control in .NET 4.6 and the planned features
for C# 7.1, 7.2 and 8.0 related to more mechanical sympathy.

------
posnet
I think that Adrian Colyer's coverage of one of the Pony papers is the best
overview of the Pony capability system.

I've found that the capability system is both the most exciting part of Pony
and the most difficult part to grok for a new comer.

[https://blog.acolyer.org/2016/02/17/deny-
capabilities/](https://blog.acolyer.org/2016/02/17/deny-capabilities/)

~~~
spooneybarger
You aren't alone. Reference capabilities are the hardest thing for most folks
to get a handle on, particularly as they relate to generics.

We have a section of the website on learning Pony that focuses on a "plan of
action" for learning reference capabilities:

[https://www.ponylang.org/learn/#reference-
capabilities](https://www.ponylang.org/learn/#reference-capabilities)

------
Animats
Interesting. Looking forward to more comments on this.

* It looks like exceptions carry no error information. When something goes wrong, you know nothing. Is that right?

* Calling finalizers from GC is usually troublesome. They get called late, so they can't be relied to close files and such. They also have to be prevented from making trouble by doing things you can't do during GC, or "re-animating" the object being deleted. How's that handled?

* The notion that variable type is established at initialization is becoming mainstream. How about extending that to structures? The fields of structures could get their types inferred from the structure constructor. (There was a statically typed variant of Python, Shed Skin, which did this.)

~~~
spooneybarger
> * It looks like exceptions carry no error information. When something goes
> wrong, you know nothing. Is that right?

Yes and no. You know something went wrong. `error` is supposed to only be used
when it indicates a specific thing that went wrong. If you need error
information, you should use a union type ala Rust.

There's been discussion on the Pony core team to change the name from
"exception" has that carries a lot of expectations these days (folks generally
expect that they will be akin to exceptions in Java et al)

------
jksmith
God damn there's some good ideas here.

pony: class Foo[A: Any val] c#: public class MyGenericArray<T> rust: fn
foo<T>(T) { ... } golang: none, because existing examples (outside of pony)
too complicated

Which most obviously suggests a generic func? Geez, took us this long to just
reach some clarity? Nice job, Pony.

More: 1 + 2 * 3 // wont compile 1 + (2 * 3) // will compile

yes! I have devs with college degrees who don't understand operator
precedence.

Liking what I see so far. Nice mix of low cognitive load/high
expressiveness/safety. Keep at it.

~~~
tomsmeding
> yes! I have devs with college degrees who don't understand operator
> precedence.

Bitwise operators in C-like languages have precedences that make no sense at
all; I can't remember those either. (Even though they _sort-of_ make sense if
you consider their historical heritage... no excuses though.) But do you
really see software developers with a university degree that mess up the
precedence of times and plus? I shudder when thinking about them working with
my code. I would really appreciate to be able to write e.g.

    
    
        a + b == 0 || c * d - e > f / g
    

without a misunderstanding of precedence. Why is that not a basic feature in
the first programming course one gets? It certainly was in mine, _two years
ago_.

EDIT: is there any way to sanely embed an asterisk in normal text here?

------
lindig
The web site promises a proof for type safety and links to a paper
[https://www.ponylang.org/media/papers/fast-
cheap.pdf](https://www.ponylang.org/media/papers/fast-cheap.pdf) but the way I
understand the paper it doesn't provide a proof. It contains a type system but
no proofs of its properties. What am I missing here?

~~~
alimw
Maybe this one?
[https://www.ponylang.org/media/papers/opsla237-clebsch.pdf](https://www.ponylang.org/media/papers/opsla237-clebsch.pdf)

~~~
lindig
It doesn't contain a proof for the type system either.

------
equalunique
Glad to see this on HN. Just a couple weeks ago I stumbled onto Pony. Seems
wonderful. Currently I am studying Erlang and Haskell with the hopes of
combining the two. Pony seems to achieve a similar aim on it's own. I like
that.

------
amiramix
Pony actors are not really Erlang-like. In Erlang the scheduler is able to
switch between processes at any point during execution (preemptive scheduler)
and is also able to garbage collect unused memory in the process at any point
during execution.

In Pony developers must write behaviours in a way that allows the scheduler to
give CPU to other behaviours and to run GC periodically to collect unused
memory. Otherwise other behaviours won't be able to run or will consume too
much memory.

[https://tutorial.ponylang.org/gotchas/](https://tutorial.ponylang.org/gotchas/)

Erlang processes are also much smarter. They can be linked to each other to be
notified when their linked counterparts die. This allows to create a well
structured hierarchy of processes, each one with a different role to fulfil in
the application.

[http://erlang.org/doc/design_principles/des_princ.html](http://erlang.org/doc/design_principles/des_princ.html)

A completely separate issue is their different approach to handling errors.
Pony, similarly to Rust, tries to prevent the developer from crashing the
application. Usually they do a decent job, but situation where the actor will
need to crash or will never return are inevitable (see gotchas above, also
imagine some dodgy code executed through FFI, etc).

Erlang takes a "let it crash" approach to managing those situations. Its BEAM
(runtime, or VM in which the processes run) is the core that executes all
processes. The core is not supposed to crash under normal circumstances but
the processes are expected to crash as soon as they can't recover from an
error.

[http://lists.ponylang.org/pipermail/ponydev/2016-February/00...](http://lists.ponylang.org/pipermail/ponydev/2016-February/000291.html)

------
snappyTertle
How does fault tolerance compare to Erlang? This was what made Erlang so great
IMO

------
xedrac
Pony looks amazing. This is the first time I've heard of it, but I'm really
excited to dive in. I'm only half way through the tutorial and there's already
a lot to love. It feels like a cross between Python, Erlang, Rust and Haskell,
with a dash of Go. The result is a surprisingly well thought-out language.

------
scanr
I like that env is passed in so that stdout isn't a global.

------
Ericson2314
+1 rust needs more reference types and now I have more ammo to say why.

-2 alias types and especially ephemeral types. Anonymity should be no big deal (e.g. lambda is boring, closing over variables is interested). This seems like a monkey patch over not respecting that principle.

------
Ericson2314
I'll keep on writing Rust and Haskell until I learn more about why I should
love the actor model, but I hope this could someday kill Erlang and Elixer.

Good job for being much more interesting than your average new PL post.

~~~
andruby
Why would you want this to kill Erlang and Elixir? Bad experiences?

~~~
burntrelish1273
Not to get into religious wars, but Erlang and Elixir generally also rock.
Caveats: documentation, error messages and REPL could be better.

Pony looks interesting and I hope it develops further.

------
jeffdavis
What kind of runtime requirements does it have?

~~~
GolDDranks
Seems to be garbage collected and the async behaviors dispatched into a
threadpool, but no pre-emption.

~~~
Matthias247
As far as I remember it is not only no pre-emption, but also no garbage
collection inside a single actor method invocation. Which has some advantages
but also the downside that longer-running and allocation-rich operations might
need to be split up into multiple async actions.

But maybe that model changed in the meantime.

~~~
spooneybarger
At this time, that is still the case.

------
floatboth
"better-than-Rust safe memory sharing" lol it's just garbage collection

~~~
stewbrew
A GC doesn't make data sharing in multithreaded applications safe.

~~~
dozzie
Once you have "Erlang-like actors", you don't have data sharing.

~~~
vanderZwan
You do in Pony. One point of the type system is to allow safe passing of data
between actors without copying everything.

~~~
dozzie
Then you don't have "Erlang-like actors", which is an implementation of CSP
(unintended, designed separately, but still).

Unless you mean that some data is shared, but cannot be modified, but this
would be semantically identical to not sharing anything.

~~~
bascule
Erlang puts all binary data on a heap which is shared between actors

~~~
dozzie
I said already:

> [...] this would be semantically identical to not sharing anything.

Erlang's data sharing (and no, not _all_ binary data, just over a certain
threshold; if you want to nitpick, be diligent and precise) is merely
optimization trick, highly uninteresting when it comes to discussing type
systems (because its semantics are identical to not sharing anything at all).

BTW, if you talk about Erlang, use proper Erlang's terminology. Erlang doesn't
have "actors", it has "processes".

