On Mon, Aug 19, 2019 at 7:46 AM Lassi Kortela <xxxxxx@lassi.io> wrote:
 
I would still slightly favor an opaque not-yet-launched-process object
but the plist approach is a pretty good approximation.

I'm not much in favor of the Builder pattern, because it involves creating a mutable object and then setting it up with a series of mutator calls.  It's really a substitute for not having keyword arguments, and plists plus quasiquotation provide what amounts to first-class keyword argument lists that are independent of procedure calls.  (Note: the "extend-syntax" mention on slide 17 is an older name for syntax-rules, but long obsolete.)

See also more generally Peter Norvig's slides at <http://norvig.com/design-patterns/design-patterns.pdf> on why patterns are signs of the lack of fully capable abstraction in non-Lisp languages.

Have to think some more about (process-wait ...) & co. A unified polling
procedure to poll all kinds of objects is really convenient for users
and probably for implementors as well. Is a process-only poller
trivially implementable as a special case of a generic poller? Probably.

It's tricky, I think.  As best I understand it you have to trap SIGCHLD and then do special things with EINTR on the select/poll.  By contrast, just checking for process terminations is easy: use the waitpid() function with the WNOHANG flag.

Another of my opinions:  the One Big Event Loop is very much an anti-pattern.  Imagine trying to write a recursive descent parser, or just a program that has to interleave reading from multiple sources, in a world in which file reads are asynchronous and the only way you know if the OS has put data in your buffer is receiving an event!  This is responsiveness not to the choices of the user but to the vagaries of the disk controller.  (Even worse would be systems, which have actually existed, in which you are sent a signal when reads/writes complete, but at least the techniques for converting signals into queued events are well-understood.) 

The Right Thing here is coroutines/threads/futures and their partner, go-channels, the lightweight version of processes and pipes.  On top of my proposed interface it would be easy to have a thread that waits for process termination and puts the process object into a go-channel, which the rest of the application can read as desired.  And because go-channels trivially have their own select (a macro), it becomes straightforward to selectively reconstitute whatever sources of events you need to interleave without being troubled by the rest.


John Cowan          http://vrici.lojban.org/~cowan        xxxxxx@ccil.org
The first thing you learn in a lawin' family is that there ain't
no definite answers to anything.  --Calpurnia in To Kill A Mockingbird