This language claims to be "capabilities-secure", which I assumed meant that it uses capability-based security and is an object-capability language. This got me excited -- my work on Sandstorm.io and Cap'n Proto uses capability-based security heavily, and a high-performance object-capability language would be awesome to have (the existing ones are mostly dynamically-typed and slow, though you can use capability-based design without using a capability-based language, as many programs and most OS's actually do to some extent).
Unfortunately, it turns out they have simply coopted the term to mean something completely different. According to the documentation: "Pony capabilities are completely new, no other language has them."[0]
Please think of a new word for this; don't redefine one (or a pair) that is widely-used already.
The term "capability” is much older than Pony, and the concept was proposed in the 60s. We would have loved to use a different word, but there are not enough different recognisable words in the English language.
We use capabilities in Pony to statically avoid data races - not for security. But we believe that Pony's capabilities can also be developed further to support security - would be great to try and program Sandstorm’s security with them.
The term "capability" is perfectly appropriate here. A capability is something that defines how you can use what it points to. It's often used in the security context, but is also used the way Pony uses them (to define how the holder of a reference can mutate the target object).
I found interesting what Rust's Graydon Hoare had to say about it:
"It's very similar to earlier versions of rust. In terms of actor local GC, language provided scheduling of actors, separated function and async invocation system, mixed structural and nominal types, and an overabundance of language supported reference qualifiers. I think they did a good job at it, certainly much better than I did, but I'd be nervous about the cognitive load of the reference qualifiers (capabilities). See this page for example, or the previous few in the tutorial. We had that sort of cognitive load on variables early on and people basically rejected the language because of it, as well as associated compositionality problems. The many years of design iteration had a lot do to with factoring that space into fewer, more essential and general qualifiers. Slow, tedious, world breaking refactoring work. I hope for pony's sake this doesn't happen to them too -- it looks really nice -- but that's my biggest worry for it."
Indeed, the type system when explained in detail is not that simple. Nevertheless, we believe that it can be used without detailed knowledge.
In our experience, programmers can pick up the system fast (e.g. after a 2 hour discussion).
Similarly, programmers can easily write programs which type-check, even if they do not have a deep understanding of the type system (e.g. they need not memorise the table you mentioned). Type-checking is enough - given the guarantees by the type system, (data-race freedom and atomicity).
The use of defaults reduces the annotation burden - typically to only 10%-20% of locations which allow them.
Regarding annotations, the "Fast & Cheap" paper contains the following:
The language uses carefully chosen default capabilities
to minimise the required annotations. In addition, the compiler guides the programmer as to which annotations should be used, infers annotations locally, and performs automatic recovery in some circumstances. As a result, when implementing LINPACK GUPS (in app. F) we require just 8 capability annotations and 3 uses of recover in 249 LOC. In approximately 10k LOC in the standard library, 89.3% of types required no annotation.
This is bike shedding but I wonder if better names for the capabilities could help?
box --> view (as in view but don't touch) or ro(read-only)
trn --> once
This is incredibly cool. I read through the whole tutorial, and I love what I see, but I recommend putting some code samples on the front page.
Syntax may be less important than a language's features, but it isn't until the 4th page of the tutorial that I even have an inkling of what code in Pony looks like.
Agreed too. Here my user experience with the presentation.
Once I've understand it was a new language (cool name btw), I've look for the Hello-world example to see if the language was easy enough for me. I've found the link after reading the HN comment: http://tutorial.ponylang.org/getting-started/helloworld/
Then, I've quickly read the part on concurrent programming. But I've not understood how it is easier with Pony. It's very frustrating. So far, my understanding is there is class (called actor) that can discuss together by sending each other immutable object. I would like to see some code in the tutorial that show how concurrency is easily done in Pony.
"Among these, Pony is the only language that concurrently garbage collects actors."
I must not be understanding that claim correctly. Erlang does garbage collection on a per actor basis (at least that's my understanding). If the claim is that multiple actors can garbage collect simultaneously, then I guess that means Erlang only GCs one actor at a time. If so, why can't Erlang GC multiple actors at a time? It does full SMP for actor execution.
> If so, why can't Erlang GC multiple actors at a time? It does full SMP for actor execution.
It does. The article is incorrect. Erlang has a fully concurrent garbage collector among actors. One actor's GC running on one CPU scheduler will not interfere with execution of actors running in other CPU schedulers.
Erlang can "leak" processes if the process doesn't exit once it's no longer needed. Pony (I assume) will clean up a process automatically once there are no more references to it.
I'm wondering about something. In big systems you'll see actors on different platforms communicating with eachother. For example, a javascript actor would communicate with a server actor. How would garbage collection work in that case? Would cycles be detected across machine boundaries?
From the benchmark results, this is not much faster than Erlang. Also the graphs only cover 12 cores, while it claims that "Applications can run on a virtually infinite processor count and on arbitrarily large clusters". I would love to see how it scales on thousands of cores.
It looks good, but is language alone enough these days? Reminds me of Axum C# research dialect. Microsoft decided to implement it as a framework in the end - Orleans. So did Scala. And wouldn't F# + Akka.NET be just as safe?
In Akka, message arguments have to be immutable objects - similarly for Erlang; Pony can pass isolated references which can be mutated and passed on, while still being data-race free. Scala is based on Java, and thus it is not data-race free - unless the program has been crafted very carefully.
Data races are a subset of all race conditions. We don't claim that it's impossible to wait on a network message that never arrives, of course!
However, Pony makes a messaging order guarantee that's much stronger than is typical for the actor model. It guarantees causal messaging. That is, any message that is a "cause" of another message (i.e. was sent or received by an actor prior to the message in question) is guaranteed to arrive before the "effect" if they have the same destination.
That guarantee is achieved with no runtime cost, which is pretty fun.
Pony still allows unbounded non-determinism, of course, but causal messaging gives a very comfortable guarantee to the programmer.
Sorry about that, we'll get more docs up as soon as we can.
For now, check out some of the included packages, like net/ssl. That calls C extensively (libressl, or openssl if you like). Or regex, which uses PCRE2.
I couldn't find any information about the authors of this language. It seems like a fairly accomplished yet complex project, so it would be quite good to know who are the people working on it.
Looks very promising, hopefully there will be a strong community around it, imho communities make or break a language or a framework no matter how good the syntax or the features are.
An unusual little feature is that assignment returns the old value of the target, e.g. a = b returns the old value of a, so that a = b = a just swaps the contents of a and b.
No. Dynamic linking is possible, for example with C libraries. 'No loadable code' means that a programs code is not modified during runtime, nor extended with new code (for example like java applets or RMI applications). We have been looking into hot code loading though.
It's also worth noting that the language does have a None primitive, but the distinction from nil or null is that the concept of "nothing" is wrapped in it's own type entirely. This means that it would be a type violation for a method of return type String to ever return a None. Instead, a method that you expect to return a String or a None would need to have a union return type of (None | String).
Obviously, I have never written anything in Pony, but this absolutely seems like an advanced use case. It exists because 'C' has a concept of null, so it needs to be handled. The manual even admits that all bets are off when dealing with the FFI.
One class having a method called "is_null" doesn't mean that the language has null built into it or any inherant concept of what that means. Just like having a method called "is_functional" doesn't mean it's a functional language.
Looks like the `handle` in question there in the File module is an instance of a Pointer, which presumably is some sort of wrapper around a raw pointer. It has null in the sense that the pointer can be null; this isn't the same thing as how nulls are traditionally used (e.g. an "empty object" which can appear in the place of where an actual object might be). So it's not a language level concept.
I'm guessing the capabilities correspond to polarized substructural types plus additional structure for who can read/write to a given area of memory (http://www.cs.cmu.edu/~fp/papers/fossacs15.pdf).
i.e.: iso = linear, val = affine, ref = unrestricted, box = readable, trn = readable/writeable, tag = uniqueness?
Capability defaulting seems a little dangerous (not that it's not type safe, but it having such information be implicit seems like a good way to encourage people to forget about it; on the other hand, if the compiler is good enough about warning people it shouldn't be a problem).
I'm not sure subtyping is worthwhile for this language (since it complicates the type system without much of a gain wrt constrained polymorphism).
Can you put up some example applications? The tutorial only has code snippets. I don't want to look at individual features in isolation, I want to get a feel for how one solves problems in the language.
1. Because Pony is both type and exception safe, actors (the Pony equivalent of an Erlang process) don't fail in the catastrophic sense. Right now, if an actor wants to report that it can't go on to some other actor, it just sends out messages. Obviously, we are big fans of Erlang, and big fans of the Erlang supervisor pattern, so we'll be writing a Pony package that puts a nice interface around this.
2. Yes! Pony has first class pattern matching already (along with algebraic data types, i.e. tuple types, union types, and intersection types, to make pattern matching really useful). It allows matching both on type and on standard or programmer defined structural equality. As I mentioned, we're big Erlang fans, so we definitely won't ignore stuff like this.
[+] [-] kentonv|11 years ago|reply
Unfortunately, it turns out they have simply coopted the term to mean something completely different. According to the documentation: "Pony capabilities are completely new, no other language has them."[0]
Please think of a new word for this; don't redefine one (or a pair) that is widely-used already.
[0] http://tutorial.ponylang.org/capabilities/introduction/
[+] [-] rdtsc|11 years ago|reply
That was (is?) all about capabilities.
http://erights.org/elang/index.html
[+] [-] decklebench|11 years ago|reply
We use capabilities in Pony to statically avoid data races - not for security. But we believe that Pony's capabilities can also be developed further to support security - would be great to try and program Sandstorm’s security with them.
[+] [-] rayiner|11 years ago|reply
[+] [-] tcard|11 years ago|reply
"It's very similar to earlier versions of rust. In terms of actor local GC, language provided scheduling of actors, separated function and async invocation system, mixed structural and nominal types, and an overabundance of language supported reference qualifiers. I think they did a good job at it, certainly much better than I did, but I'd be nervous about the cognitive load of the reference qualifiers (capabilities). See this page for example, or the previous few in the tutorial. We had that sort of cognitive load on variables early on and people basically rejected the language because of it, as well as associated compositionality problems. The many years of design iteration had a lot do to with factoring that space into fewer, more essential and general qualifiers. Slow, tedious, world breaking refactoring work. I hope for pony's sake this doesn't happen to them too -- it looks really nice -- but that's my biggest worry for it."
http://www.reddit.com/r/rust/comments/34rszb/pony_type_and_m...
[+] [-] SnowyOwl|11 years ago|reply
In our experience, programmers can pick up the system fast (e.g. after a 2 hour discussion).
Similarly, programmers can easily write programs which type-check, even if they do not have a deep understanding of the type system (e.g. they need not memorise the table you mentioned). Type-checking is enough - given the guarantees by the type system, (data-race freedom and atomicity).
The use of defaults reduces the annotation burden - typically to only 10%-20% of locations which allow them.
[+] [-] decklebench|11 years ago|reply
Regarding annotations, the "Fast & Cheap" paper contains the following:
The language uses carefully chosen default capabilities to minimise the required annotations. In addition, the compiler guides the programmer as to which annotations should be used, infers annotations locally, and performs automatic recovery in some circumstances. As a result, when implementing LINPACK GUPS (in app. F) we require just 8 capability annotations and 3 uses of recover in 249 LOC. In approximately 10k LOC in the standard library, 89.3% of types required no annotation.
[+] [-] renox|11 years ago|reply
[+] [-] ShaneWilton|11 years ago|reply
Syntax may be less important than a language's features, but it isn't until the 4th page of the tutorial that I even have an inkling of what code in Pony looks like.
I'm excited to give this a try!
[+] [-] olivier1664|11 years ago|reply
Once I've understand it was a new language (cool name btw), I've look for the Hello-world example to see if the language was easy enough for me. I've found the link after reading the HN comment: http://tutorial.ponylang.org/getting-started/helloworld/
Then, I've quickly read the part on concurrent programming. But I've not understood how it is easier with Pony. It's very frustrating. So far, my understanding is there is class (called actor) that can discuss together by sending each other immutable object. I would like to see some code in the tutorial that show how concurrency is easily done in Pony.
[+] [-] barrelrider|11 years ago|reply
[+] [-] partisan|11 years ago|reply
[+] [-] phamilton|11 years ago|reply
I must not be understanding that claim correctly. Erlang does garbage collection on a per actor basis (at least that's my understanding). If the claim is that multiple actors can garbage collect simultaneously, then I guess that means Erlang only GCs one actor at a time. If so, why can't Erlang GC multiple actors at a time? It does full SMP for actor execution.
[+] [-] rdtsc|11 years ago|reply
It does. The article is incorrect. Erlang has a fully concurrent garbage collector among actors. One actor's GC running on one CPU scheduler will not interfere with execution of actors running in other CPU schedulers.
[+] [-] panic|11 years ago|reply
[+] [-] amelius|11 years ago|reply
[+] [-] xjia|11 years ago|reply
[+] [-] SnowyOwl|11 years ago|reply
[+] [-] M8|11 years ago|reply
[+] [-] SnowyOwl|11 years ago|reply
[+] [-] nordicway|11 years ago|reply
[+] [-] 0cachecoherency|11 years ago|reply
However, Pony makes a messaging order guarantee that's much stronger than is typical for the actor model. It guarantees causal messaging. That is, any message that is a "cause" of another message (i.e. was sent or received by an actor prior to the message in question) is guaranteed to arrive before the "effect" if they have the same destination.
That guarantee is achieved with no runtime cost, which is pretty fun.
Pony still allows unbounded non-determinism, of course, but causal messaging gives a very comfortable guarantee to the programmer.
[+] [-] vortico|11 years ago|reply
[+] [-] 0cachecoherency|11 years ago|reply
For now, check out some of the included packages, like net/ssl. That calls C extensively (libressl, or openssl if you like). Or regex, which uses PCRE2.
[+] [-] bsaul|11 years ago|reply
[+] [-] decklebench|11 years ago|reply
[+] [-] ramigb|11 years ago|reply
[+] [-] joseraul|11 years ago|reply
[+] [-] rdtsc|11 years ago|reply
Anyone know what version 6.1 is refering to? Latest Erlang OTP version is 17.5. Version 11 was released sometimes 10 years ago.
[+] [-] istvan__|11 years ago|reply
Erlang/OTP 17 [erts-6.4]
[+] [-] lmz|11 years ago|reply
[+] [-] decklebench|11 years ago|reply
[+] [-] Radle|11 years ago|reply
What the hell am I missing?
[+] [-] n3otec|11 years ago|reply
[+] [-] iamd3vil|11 years ago|reply
[+] [-] kibwen|11 years ago|reply
[+] [-] n3otec|11 years ago|reply
[+] [-] teamhappy|11 years ago|reply
[1]: https://github.com/CausalityLtd/ponyc/search?utf8=%E2%9C%93&...
Also, your 3-clause BSD license only has two clauses.
[+] [-] ShaneWilton|11 years ago|reply
It's analogous to Maybe, in Haskell.
[+] [-] Nycto|11 years ago|reply
https://github.com/CausalityLtd/ponyc/blob/975d9f6c60553030e...
Obviously, I have never written anything in Pony, but this absolutely seems like an advanced use case. It exists because 'C' has a concept of null, so it needs to be handled. The manual even admits that all bets are off when dealing with the FFI.
[+] [-] barrelrider|11 years ago|reply
[+] [-] thinkpad20|11 years ago|reply
[+] [-] taktoa|11 years ago|reply
Capability defaulting seems a little dangerous (not that it's not type safe, but it having such information be implicit seems like a good way to encourage people to forget about it; on the other hand, if the compiler is good enough about warning people it shouldn't be a problem).
I'm not sure subtyping is worthwhile for this language (since it complicates the type system without much of a gain wrt constrained polymorphism).
[+] [-] scott_s|11 years ago|reply
[+] [-] n3otec|11 years ago|reply
[+] [-] panic|11 years ago|reply
1. How does process failure and recovery work?
2. Are there any plans to add binary patterns? That's one thing I'm sure I'd miss from Erlang if I wanted to write a server in this language.
[+] [-] 0cachecoherency|11 years ago|reply
2. Yes! Pony has first class pattern matching already (along with algebraic data types, i.e. tuple types, union types, and intersection types, to make pattern matching really useful). It allows matching both on type and on standard or programmer defined structural equality. As I mentioned, we're big Erlang fans, so we definitely won't ignore stuff like this.
[+] [-] Merkur|11 years ago|reply
http://tutorial.ponylang.org/capabilities/introduction/ is the best concise description why concurrency is hard I read until now.
[+] [-] n3otec|11 years ago|reply