[HN Gopher] Pony Programming Language
___________________________________________________________________
Pony Programming Language
Author : curling_grad
Score : 135 points
Date : 2022-12-13 15:56 UTC (7 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| samsquire wrote:
| I am interested in Pony due to the compiler maintaining safety
| while multithreading.
|
| I am working on a multithreaded language that has its own
| interpreter and compiler that codegens targeting it.
|
| I use message passing but shared memory mailboxes using a
| lockfree algorithm.
|
| I am trying to solve a multithreading problem which is the
| sharing of objects between threads. I want shared memory
| semantics between separate interpreters but avoiding copying.
|
| For an interpreter to be aware of an object it needs to have a
| pointer to it. So I need to update a book keeping for the object
| to refer to it.
| insanitybit wrote:
| (This is all based on my recollection) Pony does this through
| reference capabilities, ownership, and garbage collection.
|
| Basically in Pony you can describe memory as:
|
| 1. Single Ownership, Immutable
|
| 2. Single Ownership, Mutable
|
| 3. Shared Ownership, Immutable
|
| 4. Shared Ownership, Mutable
|
| If you're moving (1) or (2) that's basically free.
|
| If you're sharing (3) you just need an atomic reference count.
|
| If you're sharing (4) you need an atomic reference count and
| some sort of synchronizing primitive, such as a mutex (or maybe
| the runtime can understand how to schedule things such that
| they don't race, don't know).
|
| In Pony these reference capabilities all have names that I
| don't remember and there are also ways to "recover" a
| capability, basically translating one into another, which was
| one of the more complex features for me to get my head around.
|
| That's basically how I recall it working, although the
| reference counting implementation is very interesting and they
| wrote a paper about it (Orca).
| zozbot234 wrote:
| Worth noting that Rust also supports "Shared Ownership,
| Immutable" data - that's what Arc<T> gives you when T has no
| interior mutability, and thus implements Sync by default. (By
| contrast, a T with interior mutability needs explicit
| atomicity or synchronization, or else cannot have its access
| shared by multiple threads.)
| wiremine wrote:
| A previous conversation:
| https://news.ycombinator.com/item?id=17195580
|
| On a sort-of-related topic: I've been checking out the Inko
| programming language, which has some similar goals/ideals as
| Pony:
|
| https://inko-lang.org/
|
| Inko lists Erlang and Pony as inspiration for its concurrency
| model:
|
| "Inko uses lightweight processes for concurrency, and its
| concurrency model is inspired by Erlang and Pony. Processes are
| isolated from each other and communicate by sending messages.
| Processes and messages are defined as classes and methods, and
| the compiler type-checks these to ensure correctness."
| treuks wrote:
| looks cool to me, really wish they had standard library
| documentation and better editor support, but it's obviously
| waaay too young for this to be critical. i can see this
| maturing into a really nice web-backend language though. typed
| elixir with rust error handling and algebraic types? sign me up
| 0xTadash1 wrote:
| I always wonder when I come across a text like this what a
| lightweight process is. Is it different from just a thread? Or
| is it a type of lightweight/virtual thread?
| jeremyjh wrote:
| Yes it is a lightweight thread or "green" thread. Coroutines
| that are scheduled by the languages runtime across a pool of
| multiple OS threads and are implemented using an event loop
| that resumes a coroutine whenever the IO it was blocked on is
| available, sort of like if in Node all the async/await
| keywords were implemented for you automatically on every IO
| OP.
|
| Some languages (Erlang, Go, Haskell) have green threads with
| preemptive scheduling on CPU loops (though Go only preempts
| at function boundaries IIRC) but Pony does not, actors have
| to cooperate.
| aidenn0 wrote:
| There are multiple definitions of LWPs. I think the way it is
| being used here is a user-scheduled thread. In the old Unix
| days it meant "kernel thread"
| ch4s3 wrote:
| Building a typed, OO language inspired by Erlang on top of Rust
| seems like a bit of a platypus if that makes sense. I'm really
| wondering who is using this other than former Pony users.
| CobrastanJorji wrote:
| I want to thank whoever wrote the "Why Not To Use Pony" bullet
| points. They're quite honest and helpful. Most of these sorts of
| pages are 110% "rah rah our language is the best for every
| possible situation, which makes it hard to figure out how to
| evaluate them. For me personally, this has seemed worst with
| database products. No matter what the database's actual pros and
| cons are, their project pages will swear that they are the best
| at every possible scenario that might involve data.
| [deleted]
| emmelaich wrote:
| Where is that list?
| theIV wrote:
| https://www.ponylang.io/discover/#why-not-pony
| jevgeni wrote:
| is it just me, or is it super difficult to find code samples -
| even in the tutorial?
| kulibali wrote:
| The fourth link on the home page is "Example Pony Applications"
| Pet_Ant wrote:
| https://tutorial.ponylang.io/getting-started/how-it-works.ht...
| warpspin wrote:
| No, it's not just you. Huge mistake, in my opinion. If I see a
| page for a new programming language, I want to be one click
| away from code samples.
| augustk wrote:
| Indeed, like vapourware almost.
| Thaxll wrote:
| Isn't that language dead? Some startup used a new language
| because apparently nothing else in the world could fit their use
| case ( which was simple ) only to move to Rust after chocking
| discovery that it was a terrible idea from the start.
|
| https://web.archive.org/web/20171028135810/https://blog.wall...
|
| Then:
|
| https://www.wallaroo.ai/blog/wallaroo-move-to-rust
| jcarr25- wrote:
| They used Pony as a good fit for their first project. They
| later made a second project with better market fit, and for
| that project Rust was a better fit.
| dang wrote:
| Can you please make your substantive points without breaking
| the site guidelines? They include:
|
| " _Don 't be snarky._"
|
| " _Please don 't post shallow dismissals, especially of other
| people's work. A good critical comment teaches us something._"
|
| https://news.ycombinator.com/newsguidelines.html
| Davidbrcz wrote:
| Last time I checked, it was language backed by a research
| group.
| wiremine wrote:
| I'm not sure, but the last commit on the github repo was 12
| hours ago.
| Mikeb85 wrote:
| Development has definitely slowed and the creator has moved on
| to other things.
|
| I've played around with it and my main takeaway is that it's
| easier to create an actor system in an existing language than
| to create an entire ecosystem around Pony.
| zfxfr wrote:
| I wish there was some code samples. Just to get an idea of how it
| looks like. I browsed the website but could not find any.. Except
| for the playgroud with only one "hello world"
| reidrac wrote:
| There are a few, but you are right that they could be more
| accessible:
| https://github.com/ponylang/ponyc/tree/main/examples
|
| (I had the same problem)
| dang wrote:
| Related:
|
| _Ask HN: Why didn 't Pony take off?_ -
| https://news.ycombinator.com/item?id=31606084 - June 2022 (3
| comments)
|
| _We moved from Pony to Rust_ -
| https://news.ycombinator.com/item?id=28777306 - Oct 2021 (175
| comments)
|
| _Pony - High-Performance Safe Actor Programming_ -
| https://news.ycombinator.com/item?id=25957307 - Jan 2021 (152
| comments)
|
| _Pony, Actors, Causality, Types, and Garbage Collection_ -
| https://news.ycombinator.com/item?id=24398469 - Sept 2020 (29
| comments)
|
| _Pony: Lock-less, data-race-free concurrency_ -
| https://news.ycombinator.com/item?id=24201754 - Aug 2020 (1
| comment)
|
| _Pony 0.33.1_ - https://news.ycombinator.com/item?id=21784698 -
| Dec 2019 (2 comments)
|
| _Pony 0.29_ - https://news.ycombinator.com/item?id=20370448 -
| July 2019 (19 comments)
|
| _Pony 0.27.0 has been released_ -
| https://news.ycombinator.com/item?id=19285762 - March 2019 (1
| comment)
|
| _Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart_ -
| https://news.ycombinator.com/item?id=19241427 - Feb 2019 (143
| comments)
|
| _Pony 0.25.0 released_ -
| https://news.ycombinator.com/item?id=18212633 - Oct 2018 (38
| comments)
|
| _Show HN: Pony Programming Workshop_ -
| https://news.ycombinator.com/item?id=17619483 - July 2018 (5
| comments)
|
| _Introduction to the Pony programming language_ -
| https://news.ycombinator.com/item?id=17195580 - May 2018 (72
| comments)
|
| _The Snake and the Horse: How Wallaroo 's Python API Works with
| Pony_ - https://news.ycombinator.com/item?id=16768706 - April
| 2018 (8 comments)
|
| _Some high level information about the Pony programming
| language_ - https://news.ycombinator.com/item?id=16619264 - March
| 2018 (10 comments)
|
| _Why we wrote our Kafka Client in Pony_ -
| https://news.ycombinator.com/item?id=16264845 - Jan 2018 (95
| comments)
|
| _Dynamic Tracing a Pony and Python Program with DTrace_ -
| https://news.ycombinator.com/item?id=15953050 - Dec 2017 (2
| comments)
|
| _Why we used Pony to write Wallaroo_ -
| https://news.ycombinator.com/item?id=15558051 - Oct 2017 (84
| comments)
|
| _Pony Performance Cheatsheet_ -
| https://news.ycombinator.com/item?id=14999899 - Aug 2017 (35
| comments)
|
| _Pony: Combining safe memory sharing with Erlang-like actors_ -
| https://news.ycombinator.com/item?id=14676505 - July 2017 (62
| comments)
|
| _An Early History of Pony_ -
| https://news.ycombinator.com/item?id=14280565 - May 2017 (8
| comments)
|
| _Pony language 0.11.0 released_ -
| https://news.ycombinator.com/item?id=13846063 - March 2017 (52
| comments)
|
| _On the State of Pony_ -
| https://news.ycombinator.com/item?id=12331458 - Aug 2016 (40
| comments)
|
| _Using Pony for Fintech [video]_ -
| https://news.ycombinator.com/item?id=11849579 - June 2016 (6
| comments)
|
| _Using the Actor-Model Language Pony for FinTech_ -
| https://news.ycombinator.com/item?id=11297836 - March 2016 (1
| comment)
|
| _Pony Patterns: Waiting_ -
| https://news.ycombinator.com/item?id=10927475 - Jan 2016 (3
| comments)
|
| _Pony is an open-source, actor-model, high performance
| programming language_ -
| https://news.ycombinator.com/item?id=10902906 - Jan 2016 (57
| comments)
|
| _Inside the Pony TCP Stack_ -
| https://news.ycombinator.com/item?id=10762196 - Dec 2015 (1
| comment)
|
| _Pony - High Performance Actor Programming_ -
| https://news.ycombinator.com/item?id=9482483 - May 2015 (124
| comments)
| jwmcq wrote:
| I wonder if there's somewhere that people can propose a name for
| things and people can tell them why they might want to use
| something else - 'Pony' is fairly common slang for 'crap' in
| London / Southern England.
| twic wrote:
| I've lived in London and the south pretty much all my life, and
| i'm not sure i've ever heard it used to mean that. It's rhyming
| slang, right? Not sure how many cabbies are in the market for
| memory-safe systems programming languages really.
| jfk13 wrote:
| Also in/from the south (though outside London), and was not
| familiar with that usage at all. A search does turn up some
| confirmation, though (e.g.
| https://www.phrases.org.uk/meanings/287275.html).
| cpeterso wrote:
| The language was developed by people in London.
|
| > _The big reveal on why it's called "Pony"? Back in the flight
| sim days, when I would make my friends groan by telling them
| yet again about all the things I was going to do when I wrote a
| programming language, one of the people I would tell was Nathan
| Mehl. And one time, when I gave him yet another laundry list,
| he said: "yeah, and I want a pony"._
|
| But perhaps they didn't want to admit "pony" is also a
| reference to the slang term..
|
| https://www.ponylang.io/blog/2017/05/an-early-history-of-pon...
| quotha wrote:
| A pony is a small horse dude
| Normille wrote:
| I'm not from London myself but I've never heard a Londoner [or
| southerner] use Pony in that sense. I've often heard it used
| for an amount of money. PS20 I think.
|
| When I read your opening _' I wonder if there's somewhere that
| people can propose a name for things and people can tell them
| why they might want to use something else...'_ I thought you
| were going to go on to make a point about not using everyday
| words [or single letters] as the name for your new programming
| language, as they'll be unsearchable. And everyone will end up
| tagging _-lang '_ onto the end of the name, to discriminate.
|
| EDIT: I was a fiver out. A 'pony' is apparently PS25:
|
| https://www.cockneyrhymingslang.co.uk/subjects/money
| krylon wrote:
| I looked into pony a couple of years ago. The type system was
| _gorgeous_ , but the library ecosystem was very spartan.
|
| I hope they get there eventually, I liked the language itself a
| lot. The learning curve is very steep at first, but I felt that I
| got over hump after a couple of days playing with it after work.
| nikivi wrote:
| Was reading docs on actors
|
| https://tutorial.ponylang.io/types/actors.html
|
| And I wonder what makes pony actors different to Go's goroutines?
| jerf wrote:
| In general, your latter question is better asked as "what makes
| actors different from threads?", because in practice a
| goroutine is just a thread.
|
| (What makes Go different from C++ in the 1990s is more
| community practice around what concurrency patterns are most
| commonly used, rather than technical differences in the
| language. Technically Go is just a mutable threaded language;
| for this purpose details about how the threading is
| accomplished are not that important.)
|
| In general the big difference with actors is that they are
| isolated from each other in some manner that means they can't
| just reach in to some other actor's memory space and manipulate
| the memory concurrently.
|
| Languages are starting to blur the lines here. Rust's lifetime
| annotation is not on its own sufficient to call Rust an "actor-
| based language" but the fact that they also prevent
| threads/async processes from just reaching in and manipulating
| other threads/async process's value unexpectedly means you've
| certainly taken a big step in that direction. And while Go
| provides no language-level technical support for actors, I
| still have a lot of things that are _de facto_ actors in Go
| that uses scoping and export rules to confine the ability of
| other goroutines to interfere with a particular "actor"'s
| values, combined with an API that enforces message-based
| communication even though it works through what look like
| normal methods. This is not enforced at all technically by the
| language but it works better with community code than it does
| in older thread-based languages because the Go community is
| more recent and you can generally rely on libraries using
| somewhat more modern concurrency primitives, like providing
| services based on actors or actor-like objects.
|
| There are some things in programming where if you mostly follow
| some practice, you get most of the benefit. There are other
| things in programming where the benefit only kicks in if you do
| it almost entirely correctly; an example of the latter is
| Haskell's rigid insistence on functional programming and
| immutability, I'm not convinced that it's worth doing 90% of
| that but when you fully commit and build the language around
| it, there is an interesting spike in capability at the end.
|
| After programming in this space for well over a decade now, I
| kinda feel like actors are in the former case. I'm not sure you
| truly need a full language-level dedication to them to get
| _most_ of their benefits. There is a last level of confidence
| and surety you can get in a language like Erlang, but I still
| think in practice that 's just a last incremental benefit
| rather than a sudden burst in utility as you get to 100%
| purity. I think it's fine to program an actor here and an actor
| there in other languages and you get the benefits right there
| on the spot. Even what benefit there is, things like Rust gain
| in a different way. Still, I've been watching Pony with some
| interest.
| OkayPhysicist wrote:
| I have to disagree pretty strongly about the lack of a
| "sudden burst in utility" between non-pure actor model and
| the pure actor model. Erlang's (and Elixir's) VM, the BEAM
| benefits greatly from knowing, with absolute certainty, that
| it is impossible to express shared state between two actors.
|
| First off, it's garbage collection system: In Erlang, most
| actors don't get garbage collected at all until the entire
| actor is terminated and its memory freed. Long-running
| processes get handled with a little more grace than that, but
| it's very performant compared to Java's constant scanning.
|
| Likewise, certain language design decisions allow for
| optimizing the scheduling system: most obviously, Erlang's
| complete lack of loops. Want to repeat a computation?
| Recurse. That choice allows for the scheduler to be far more
| intelligent, because the new function call provides for a
| great opportunity for the process's thread to be co-opted.
|
| Another example is Erlang's seamless distribution: since no
| threads can share memory anyway, there's not a fundamental
| difference between them running on two different CPU cores or
| two different machines, save for some added latency.
|
| And, of course, the fault tolerance story. The guaranteed
| lack of shared state between two actors means that the VM can
| be certain the blast radius of a failing actor is limited to
| its context. Wipe its memory, move on. This failure handling
| model turns handling the error conditions of "invalid input",
| "missing resources", and "Frank from IT has finally snapped
| and taken a sledgehammer to one of our servers" into
| qualitatively the same thing: one or more actors have failed,
| their supervisor needs to respond appropriately.
|
| All these benefits would be diminished or at least
| qualitatively different (for the worse) in a language that
| wanted to walk the middle ground.
| kaba0 wrote:
| As far as I know the biggest diffeence between Erlang's GC
| and other GC algorithms is that the former only has to work
| on a small local heap.
|
| This also works to a degree in Java with thread local
| allocation buffers. Objects get allocated on a thread local
| basis and only move to a shared heap generation when they
| lived for long enough, or are being shared to another
| thread.
| zozbot234 wrote:
| > As far as I know the biggest diffeence between Erlang's
| GC and other GC algorithms is that the former only has to
| work on a small local heap.
|
| This is also the biggest potential upside of "pluggable",
| optional GC in a language like Rust. In most programs,
| the size of a group of references that might form an
| ownership-relevant cycle is naturally quite small; for
| the most part memory can be managed with simple RAII, and
| even refcounting (where multiple "owners" might be
| extending the lifecycle of a single object) really is
| quite rare.
|
| Leaving open the possibility of GC allows for expressing
| more programs, without reducing performance.
| kaba0 wrote:
| > for the most part memory can be managed with simple
| RAII, and even refcounting (where multiple "owners" might
| be extending the lifecycle of a single object) really is
| quite rare
|
| This is absolutely not my experience. I believe there is
| a bias here between developers using mainly low- or high-
| level languages, but these nested lifetimes are common in
| the former because these developers have learned to form
| such lifetimes, and are biased towards those.
|
| In plenty of areas lifetimes are very very dynamic (any
| language interpreter/symbolic processing, but even web
| backends).
| jasone wrote:
| Minor nit: In a language like Erlang, function calls
| (including tail recursion) are instrumented to implement
| things like preemption, GC, and statistics updates. But
| loops (backward branches) can just as easily be
| instrumented, and various imperative language runtimes do
| so.
|
| Erlang is somewhat unusual among contemporaries in how it
| multiplexes actors onto system threads. This has
| historically been quite difficult to get 100% right because
| even if you manage to make all system calls non-blocking
| (e.g. TCP socket I/O), "non-blocking" disk I/O can still
| stall computation for a relative eon. I'm pretty excited
| about io_uring because it provides a general solution to
| this problem.
| galaxyLogic wrote:
| The benefit would be if there was a language where everything
| is an actor. It would greatly simplify your programming
| model.
|
| I'm thinking of the early versions of Smalltalk which tilted
| towards this direction. Why did they abandon 'active
| objects'? I guess the hardware just wasn't there yet.
| zozbot234 wrote:
| Rust effectively accomplishes this, because mutating a
| value that's accessible by a different thread requires both
| interior mutability and a separate Sync trait, meaning that
| accesses will be properly synchronized. Some types
| implement this (atomic types, Arc, Mutex, Rwlock) but the
| default is not to, so the default is that data may only be
| mutated by a single thread at any given time.
| jerf wrote:
| There are languages where everything is an actor, like
| Erlang. I said what I said because I worked in them
| professionally for many years. While there is incremental
| benefit to being 100% actors versus 90% actors, I don't
| think it's that impressive of an incremental benefit, and
| is easily overwhelmed by many other factors. That's why I
| work mostly in Go and borrow actor structures when helpful.
| That turns out to be every non-trivial program I've written
| so far... but there's no particular benefit and often non-
| trivial costs in trying to write the _whole program_ as
| actors, rather than using actors as useful servers. The
| simplification of being able to look at something and just
| _know_ it 's an actor I don't find very helpful. It's not
| hard to document these things, or see them in the structure
| of the code.
|
| By contrast, 90% pure functional programming is a pretty
| terrible paradigm. You really need to push that number up
| to get the benefits. As you approach 100% I think the
| benefit starts to take off. But, speaking very sloppily
| since "percent pure functional programming" is kind of
| difficult to precisely define, 90% is like the worst case
| scenario. 20%, which is to say mixing it in to other
| paradigms when useful without commitment and without paying
| much price and just harvesting the low hanging fruit can be
| very nice, and 99.9% can be very powerful, but 90% is the
| worst case, where you're paying most of the price but
| getting few of the benefits of true commitment. This is
| what I mean by seeing a lot of benefit in going the full
| way. I don't see this benefit to actors. They work just
| fine embedded into large programs and deliver the vast bulk
| of their benefit without having to structure the entire
| program around them.
|
| Definitely still worth learning; I consider them a core
| technique in concurrency programming. When you can easily
| afford the message marshaling and concurrency expenses,
| they are one of the easiest ways to get concurrency without
| complexity. And most of the time, you _can_ afford those
| costs.
| insanitybit wrote:
| Pony actors:
|
| 1. Have a typed, nominal interface (called behaviors)
|
| 2. Have state
|
| Those are probably the main differences, just with regards to
| actors.
| no_wizard wrote:
| It seems to this shares a lot of similarities with Elixir. The
| biggest thing that stood out to me is Pony appears to be object
| oriented in approach where as Elixir is function in approach.
|
| Aside from Elixir being a bigger community the core goals and
| purpose seem very similar to me
| lowbloodsugar wrote:
| >Actors themselves, however, are sequential. That is, each actor
| will only execute one behaviour at a time. This means all the
| code in an actor can be written without caring about concurrency:
| no need for locks or semaphores or anything like that.
|
| I mean, sure, it's nice not to have to build this behavior in
| Java, but it can (and I and many other have) be built in Java,
| and then there's still Java's massive code base available. I have
| yet to do it in Rust, but Rust probably has great support for
| just this.
|
| But let's not pretend that this solves all problems related to
| "concurrency", such as race conditions. In fact it specifically
| only solves problems where the individual state of an actor is
| completely independent of any other actor. Sure, that's a lot of
| places if done right, but in those places, a queue driven FSM in
| Java does the job.
| twic wrote:
| To me, the interesting thing about Pony is its system of
| reference capabilities:
|
| https://blog.beardhatcode.be/2018/10/pony-capabilities.html
|
| They feel a lot like Rust's system of ownership and borrowing,
| but oriented more towards safe communication in an actor system
| rather than safe memory management.
| Vedor wrote:
| I used Pony for a small hobby project around 2 years ago. It
| looked promising and I had a lot of fun using Pony. My biggest
| gripe was lack of high quality materials to actually learn the
| language, especially that some concepts were new to me. The
| community on Zulip, including the main contributors like Sean
| Allen, were very welcoming and helpful.
| zengid wrote:
| Fun fact: the person who created Pony, Sylvan Clebsch, has been
| working on a Microsoft Research project called Verona. From it's
| README [0]:
|
| > _Project Verona is a research programming language to explore
| the concept of concurrent ownership. We are providing a new
| concurrency model that seamlessly integrates ownership._
|
| [0] https://github.com/microsoft/verona/tree/master
| pard68 wrote:
| Minor nit, it takes far too many clicks to see what the language
| looks like.
| aidenn0 wrote:
| I didn't take me too many clicks; from ponlyang.io I cliked
| "try it in your browser" and it dumped me to a hello world.
|
| Alternatively there is an examples folder on the linked GH
| page.
| Pet_Ant wrote:
| https://tutorial.ponylang.io/getting-started/how-it-works.ht...
| qorrect wrote:
| Came here to say this also, couldn't find any code samples
| after 5 clicks and gave up.
| TruthWillHurt wrote:
| I went much deeper than 5 clicks, into tutorial, about,
| getting started - no code.
|
| Only thing remotely like the syntax is the cheat sheet.
___________________________________________________________________
(page generated 2022-12-13 23:01 UTC)