Live data from Hacker News

Pony: An actor-model, capabilities-secure, high-performance programming language

ponylang.io

271–280 of 284 posts

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#271
post #255

Earlier quoted context omitted.

What is this, then? https://github.com/ponylang/ponyc/blob/main/examples/echo/ec...

It is not whitespace signficant. That is indented to assist the human reader, not the compiler.

so you're telling me this is valid Pony?

actor Main

new create(env: Env) =>

TCPListener(TCPListenAuth(env.root), Listener(env.out))

??

If so, I don't want to every see that language in my life ever again.

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#272
post #36

> The standard way to avoid these problems is to use locks to prevent data updates from happening at the same time. This causes big performance hits […] No. Modern mutex implementations [1] are extremely efficient, require only 1 byte of memory (no heap allocation), and are almost free when there's no contention on the lock – certainly much faster and much lower latency than sending messages between actors. [1] Like…

Sending a message between Actors can be just moving a pointer to a piece of shared memory. I think sending messages is more about the way you think about concurrency, more than the implementation. I have always found the "one thread doing "while True receive message, handle message" much easier to reason about than "remember to lock this chunk of data in case more than one thread should access it"

There's a whole lot of discussion below so I'm just going to tag from here.

I think of pony actors in the same way as I think of erlang actors. They have a "mailbox", and when they receive a message, they wake up, execute some amount of code, and then go back to sleep.

This is how I think about it. This is not how it is actually implemented.

Here's the key that I think many people miss about pony.

Referential Capabilities DO NOT EXIST at runtime.

So let's talk passing a String iso from Actor A, to Actor B. (iso is the capability that guarantees that this is the only reference to this object):

  // This is code in Actor A
  actorB.some_behaviour_call(consume myisostring)

The "consume myisostring" completely removes myisostring from Actor A. Any reference to it after this point will result in an "unknown variable myisostring" error from the compiler.

The reference to myisostring then gets sent to Actor B via its mailbox.

If ActorB was idle, then the message receive will cause Actor B to be scheduled and it will receive the reference to that String iso - completely isolated.

Now, if we're going to measure "performance of passing data between threads" as latency per transaction, then actor contention on a scheduler is going to be a bigger factor.

If you're measuring performance across an entire system with millions of these actions occurring, then I would argue that this approach would be faster as there is no spinning involved.

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#273

Earlier quoted context omitted.

> constant time use cases that’s a deal breaker. There are real-time safe GC algorithms. I don't know whether Pony offers that option. I would like to know.

I'm not sure I understand what you mean by "real-time safe GC algorithms", but pony is not a language that has being a "real time system" as a design goal. This pony paper here describes the pony GC algorithms and compares their performance under various scenarios to other language GCs. https://www.ponylang.io/media/papers/orca_gc_and_type_system... The charts you want to look at are on pages 19-21. It shows that ORC…

Real-time safe GC algorithms and data structures provide strong guarantees that any interruptions to the running program caused by GC activity will have a bounded duration, with strong guarantees on the upper bound of any pause. This is important in latency sensitive software and real-time software that needs to meet deadlines.

Examples include IBM's Metronome: https://www.researchgate.net/publication/220829995_The_Metro... and https://developer.ibm.com/articles/garbage-collection-tradeo...

Thanks for the ORCA link. I'll have to study it more closely but from Fig 17 it looks to have quite unpredictable jitter up to at least 20ms. Which is obviously fine for many things but not useful for other things (e.g. processing AVB streaming audio packets at line rate every 125 us).

EDIT: I originally also cited the following, however I am not sure these were the papers that I was thinking of: Baker's algorithm: https://dspace.mit.edu/bitstream/handle/1721.1/41976/AI_WP_1... also discussed here: "Baker's garbage collector performs garbage collection in real time-- the elementary object creation and access operations take time which is bounded by a constant, regardless of the size of the memory." https://web.media.mit.edu/~lieber/Lieberary/GC/Realtime/Real...

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#274

Earlier quoted context omitted.

So for baseline context, we can consider two kinds of errors; there's no standard terminology, but I'll call them "exceptional results" (caused by problems outside your process's control, like filesystem or network failures) and "runtime errors" (caused by bugs in your code, like trying to dereference a null pointer or index past the end of an array). Pony: Doesn't distinguish between exceptional results and runtime…

Pony is a strongly typed language. If you want your functions to return an Optional Type, define an Optional Type. For example, the OpenFile API returns you either a valid pony File object, or why it failed (FileEOF, FileBadFileNumber, FileExists, FilePermissionDenied, etc…). What partial functions do is ensure that all of the error cases are actively addressed by the programmer, so you don't get panics or SEGVs.

The problem is, what exactly do you do when your program hits a precondition or invariant violation?

There are basically only two possibilities: abort the process, or jump to a top-level handler that logs the error and returns a 500 response (or whatever the equivalent is, for a long-running program that's not a web server). In neither case is there any interesting decision to be made about how the direct caller should handle the error. In return, whenever you subscript an array or otherwise do anything that has preconditions or invariants, you have to add a question mark to every function that can transitively call it and every call site of same, throughout the codebase. This task requires no intelligence—it can be done algorithmically without error—so why require it?

If you could actually prevent precondition and invariant violations at compile time, that would be quite a different proposition, but Pony can't actually do that (because it requires dependent types) and the intermediate solution they've hit on appears to be the worst of all worlds.

Also, it seems perverse to have a syntax for calling fallible functions and propagating failures up the call stack, but then not allow it to be used for exceptional results, which are the kind of failure that's actually worth propagating up the call stack.

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#275

Earlier quoted context omitted.

I'm not sure I understand what you mean by "real-time safe GC algorithms", but pony is not a language that has being a "real time system" as a design goal. This pony paper here describes the pony GC algorithms and compares their performance under various scenarios to other language GCs. https://www.ponylang.io/media/papers/orca_gc_and_type_system... The charts you want to look at are on pages 19-21. It shows that ORC…

Real-time safe GC algorithms and data structures provide strong guarantees that any interruptions to the running program caused by GC activity will have a bounded duration, with strong guarantees on the upper bound of any pause. This is important in latency sensitive software and real-time software that needs to meet deadlines. Examples include IBM's Metronome: https://www.researchgate.net/publication/220829995_The_M…

It's less than a third of the others which are compared.

As with all things, we should use the correct language / runtime for the domain problems it's designed to solve.

The pony runtime makes other decisions (such as non-preemptable schedulers) which would have more of an effect on your use-case methinks.

Thank you for the discussion and your interest!

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#276

Earlier quoted context omitted.

Pony is a strongly typed language. If you want your functions to return an Optional Type, define an Optional Type. For example, the OpenFile API returns you either a valid pony File object, or why it failed (FileEOF, FileBadFileNumber, FileExists, FilePermissionDenied, etc…). What partial functions do is ensure that all of the error cases are actively addressed by the programmer, so you don't get panics or SEGVs.

The problem is, what exactly do you do when your program hits a precondition or invariant violation? There are basically only two possibilities: abort the process, or jump to a top-level handler that logs the error and returns a 500 response (or whatever the equivalent is, for a long-running program that's not a web server). In neither case is there any interesting decision to be made about how the direct caller shou…

You can do this:

  try
    somearray(outofboundindex)?
    // stuff
  else
    errorlog.write("some message")
    error
  end
Sure you can make it propogate all the way up if you really want, but ugh… what a terrible idea for instrumentation.

Pony doesn't force you to deal with errors a specific way. Pony forces you to make a choice so you can't just ignore it.

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#277
post #271

Earlier quoted context omitted.

It is not whitespace signficant. That is indented to assist the human reader, not the compiler.

so you're telling me this is valid Pony? actor Main new create(env: Env) => TCPListener(TCPListenAuth(env.root), Listener(env.out)) ?? If so, I don't want to every see that language in my life ever again.

So you like languages that treat whitespace as syntax.

That's fine, we all have our preferences :D

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#278

Earlier quoted context omitted.

The problem is, what exactly do you do when your program hits a precondition or invariant violation? There are basically only two possibilities: abort the process, or jump to a top-level handler that logs the error and returns a 500 response (or whatever the equivalent is, for a long-running program that's not a web server). In neither case is there any interesting decision to be made about how the direct caller shou…

You can do this: try somearray(outofboundindex)? // stuff else errorlog.write("some message") error end Sure you can make it propogate all the way up if you really want, but ugh… what a terrible idea for instrumentation. Pony doesn't force you to deal with errors a specific way. Pony forces you to make a choice so you can't just ignore it.

That code is only allowed in a partial context, right? So if you don't propagate it all the way up the call stack, what do you do instead?

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#279

Earlier quoted context omitted.

Right, saying that only programmers who don't solve genuine problems and instead merely follow trends and treat it as fashion (and are thus no true scotsman) care about syntax, implying their opinion doesn't count, is definitely not a no true scotsman fallacy. It totally doesn't suggest that true scotsman heed the notion that syntax doesn't matter, and that so by definition, anyone else is just some goober following…

Only a certain kind of Hacker News would make this reply

[deleted]

Re: Pony: An actor-model, capabilities-secure, high-performance programming language

#280

Earlier quoted context omitted.

Real-time safe GC algorithms and data structures provide strong guarantees that any interruptions to the running program caused by GC activity will have a bounded duration, with strong guarantees on the upper bound of any pause. This is important in latency sensitive software and real-time software that needs to meet deadlines. Examples include IBM's Metronome: https://www.researchgate.net/publication/220829995_The_M…

It's less than a third of the others which are compared. As with all things, we should use the correct language / runtime for the domain problems it's designed to solve. The pony runtime makes other decisions (such as non-preemptable schedulers) which would have more of an effect on your use-case methinks. Thank you for the discussion and your interest!

Thank you for the pointers, much appreciated.
Post reply on HN