I have a server I want to communicate with, over a Unix-domain socket. The server speaks something which used to be a simple textual command-response
protocol, but now has all sorts of strange asynchronous notifications, background jobs and other weirdness.
I already have a GUI monitor program which uses this protocol, written in Python. It's all single-threaded: there's a function you call to submit a command which returns the server's response. This is mostly satisfactory, with a couple of niggles. Firstly, there's an annoyance where I have to delay asynchronous notifications while a command is in progress, 'cos otherwise the notification handler might issue a command, and the replies get muddled up hopelessly. Secondly, background commands involve pratting about with callbacks, which is Just No Fun.
I'd like to be able to write service providers for this protocol. (There's a shiny command set for registering extra services with the server and implementing extra commands or other useful features.) I've not written any yet, but I'd like the process to be relatively painless.
What I'd really like is coroutines. Then I could have one coroutine to watch the connection to the server; background commands don't end up being significantly more messy than foreground ones (except for a little bit of faff to do with running other coroutines while we're waiting for the answer) and the interleaved-commands problem goes away.
Unfortunately, Python (my first choice) doesn't have coroutines. Well, there is an extension module which allegedly implements them but it's not part of Debian and I can't necessarily expect other users to have it installed.
Other languages I've thought about:
PerlI don't like Perl any more. Its error handling approach is Just Wrong, and I'm fed up of the mad punctuation involved in getting it to actually do anything. For an allegedly terse language, it's surprising to me that I have to type monstrosities like @{$me->{FOO}} all the time. And it doesn't have coroutines.
LispI love Lisp dearly. Common Lisp doesn't have coroutines either. There is a grim set of macros which implement continuation-passing style but they're scarcely more pleasant than doing things the hard way. Besides, hardly anyone has a Lisp system kicking about, messing with Unix-domain sockets involves getting into nonportable stuff, and making standalone runnable programs is weird. (CMUCL does have coroutines, so I could require that, I suppose.) I could use scsh, which overcomes most of these objections: it has first-class continuations already, it's not particularly grim to install (just a Debian package), standalone scripts are easy, and it supports Unix-domain sockets. But it's still a special install for many people.
RubyI recently described Ruby thus: Imagine that Perl and Smalltalk are the only survivors of a plane crash on a remote desert island: Ruby is their offspring. Ruby does have real first-class continuations, and understands Unix-domain sockets.
TclThis is largely a nonstarter, which is a shame. Tcl doesn't support Unix-domain sockets, or coroutines. This is a big shame.
Or I could go with Python anyway. I like Python, and everyone already has it installed. And I already have Catacomb bindings for it. The lack of coroutines is annoying, but I could probably fake something up using threads. (Fear!)
Any opinions?