[HN Gopher] Structured concurrency and Lua
       ___________________________________________________________________
        
       Structured concurrency and Lua
        
       Author : marcobambini
       Score  : 112 points
       Date   : 2022-09-20 12:24 UTC (10 hours ago)
        
 (HTM) web link (gist.github.com)
 (TXT) w3m dump (gist.github.com)
        
       | _ZeD_ wrote:
       | The equivalent for python is trio
       | 
       | https://trio.readthedocs.io/en/stable/
        
       | belmarca wrote:
       | Does HN have a solid book recommendation on the topic of
       | concurrency?
        
         | saw-lau wrote:
         | 'Communication and Concurrency' by Milner?
         | 
         | https://dl.acm.org/doi/book/10.5555/534666
        
         | jsty wrote:
         | The Art of Multiprocessor Programming - Herlihy & Shavit
        
       | andrewmcwatters wrote:
       | I find concurrency (and threading) concepts in Lua fun and all,
       | but these topics seem to ignore practical issues for academic,
       | historical, or theoretical ones.
       | 
       | I use Lua a lot, but the global interpreter lock or
       | lua_lock/lua_unlock implementation detail is one I don't see
       | people talk too much about.
       | 
       | It's particularly frustrating when you want to do something
       | advanced, like pull in an FFI for Lua, but also implement GIL
       | behavior.
       | 
       | I haven't ever seen someone implement this correctly. I think it
       | should be easy in theory, but I haven't given it a go in a while.
       | 
       | The current state of things is, you can use LuaJIT and accept no
       | thread safety, or use PUC-Rio Lua with a custom lua_open/lua_lock
       | implementation and use the FFI library separately. I haven't
       | actually seen anyone do the latter. So in the field, it's all an
       | untested concept, I think.
       | 
       | Maybe someone out there is doing this today and not talking about
       | it. But there's no open source solution. Lua Lanes doesn't
       | address this concern, and stylistic adaptions of cooperative
       | multitasking don't either.
       | 
       | I realize it's technically a different topic, but it's basically
       | the same area of concern.
       | 
       | Except, well, I find there to be fewer practical use cases for
       | cooperative multitasking versus preemptive.
        
       | ufo wrote:
       | This is taking advantage of coroutines and to-be-closed
       | variables.
       | 
       | To-be-closed variables were recently introduced in Lua 5.4. Lua
       | runs a destructor method when these variables go out of scope,
       | like the RAII pattern in c++.
       | 
       | Coroutines have been in Lua for quite a while now. They allow
       | cooperative concurrency (as opposed to preemptive concurrency
       | a-la threads). It works similar to async generators as found in
       | Python, C#, etc, except that Lua coroutines are stackful. You can
       | yield inside an inner function and it'll pause the whole call
       | stack. In the article, the yield is inside the async_sleep
       | function. When you call a function that yields, you don't need to
       | explicitly mark that with an "await".
        
         | JonChesterfield wrote:
         | One of the things you can do in a coroutine is spawn a new
         | process, with stdin etc wired up, and yield while waiting for
         | the new process to do things. That puts a really convenient API
         | on top of concurrent batch operations.
        
       | vanderZwan wrote:
       | > _It achieves this in ways that seem subtle to us-- clearly so,
       | since it wasn 't really discovered and applied until the late
       | 2010's_
       | 
       | I'm getting a little annoyed by the structured concurrency crowd
       | ignoring the synchronous concurrency paradigm as a historical
       | precedent. It has existed since the 1980s and as far as I can
       | tell there is a huge overlap in concepts. The only major
       | difference I'm seeing is the addition of scoped _asynchronous_
       | concurrency on top of synchronous concurrency (meaning single-
       | threaded concurrency). That 's significant for sure, but also not
       | so much that it's cool to ignore the existing previous work.
       | 
       | Here's Ceu, a language from 2011 with scoped synchronous
       | concurrency:                   input int KEY;           par/or do
       | every 1s do               _printf("Hello World!\n");
       | end           with             await KEY;           end
       | 
       | (Prints the "Hello World!" message every second, terminating on a
       | key press.)
       | 
       | And hey, since we're talking about Lua, maybe we can acknowledge
       | LuaGravity, which has existed since 2009?
       | 
       | Don't get me wrong though, I'm glad structured concurrency is
       | catching on and that new work is being done in this area.
       | 
       | [0]
       | https://en.wikipedia.org/wiki/Synchronous_programming_langua...
       | 
       | [1] http://ceu-lang.org/
       | 
       | [2] https://fsantanna.github.io/luagravity/
        
         | maxwell86 wrote:
         | Do you have some scientific references on synchronous
         | concurrency?
        
         | akkartik wrote:
         | The absence of an `await` keyword is key to structured
         | concurrency, though. Was that known before the late 2010s?
         | 
         |  _Edit_ : Maybe Erlang process trees are structured by default?
         | It's been a while so I don't remember.
        
           | Jtsummers wrote:
           | https://trio.readthedocs.io/en/stable/tutorial.html#tutorial.
           | ..
           | 
           | Even Python's Trio (which asserts that it is structured
           | concurrency) uses await. But even Ada didn't use `await`
           | (most languages didn't) and has had something very close to
           | structured concurrency since 1983 (first published spec).
           | 
           | https://learn.adacore.com/courses/intro-to-
           | ada/chapters/task...
           | 
           | One of the important parts of structured concurrency is that
           | if you have something like this:                 a
           | spawn(b)         spawn(c)
           | 
           | `a` cannot terminate until after `b` and `c` have terminated
           | (or it has to terminate them), at least not without moving
           | the tasks or spawning them inside a nursery that will survive
           | `a`'s scope. That's been baked into Ada since its first spec
           | 40 years ago (along with many other elements of structured
           | concurrency).
        
           | [deleted]
        
         | ghoward wrote:
         | I am part of the structured concurrency crowd, and I agree with
         | you.
         | 
         | We (royal we) ignore it too much.
         | 
         | I personally like some of the ideas, and I'm implementing those
         | ideas in my structured concurrency language.
        
         | mananaysiempre wrote:
         | I'd very much like to see an accessible source on synchronous
         | languages in general--a review paper maybe? So far I've only
         | seen language-specific tutorials, where the nice things about
         | the approach as such are liberally diluted with the specifics
         | of the language and general programming knowledge.
         | 
         | That said, from what I've seen Trio-style "structured
         | concurrency" is somewhat less strict than the synchronous
         | model: nurseries being tangible objects implies (1) you can
         | spawn a dynamically-specified amount of cooperative threads, as
         | you can just tell the nursery to spawn things in a loop; (2)
         | you are not limited to strict nesting, as an ancestor thread
         | can pass you a nursery closer to the root if it wishes.
         | 
         | The result of the second point is that you can maintain a tree
         | of responsibility for e.g. error propagation without having a
         | stack discipline where a parent thread's dynamic extent must
         | encompass all of its children's (though there must be an
         | ancestor with such a property). Yes, that means you're free to
         | have a single catastrophically-crashing root nursery where
         | everybody spawns whatever they want, but you're also free not
         | to (and in fact there's a sort of capability discipline for
         | that, to the extent that the host language encapsulates
         | things).
        
           | jcelerier wrote:
           | there's a few mentioned in my thesis's intro, 2.3 p.21
           | https://tel.archives-ouvertes.fr/tel-01947309/document but
           | it's by no means an exhaustive reference
        
       ___________________________________________________________________
       (page generated 2022-09-20 23:01 UTC)