Briefly, on programming IRC bots using Common Lisp

July 30, 2020 by Lucian Mogosanu

This post is quite transparently an attempt to dig deeper into that Feedbot series. There's one small problem, though, namely that writing this properly requires time, and plenty of it, clearly more than I have on my hands these days. If I were to write it properly, the result would look more akin to that CL WWW series, but since I don't, please do ask questions if you're interested. Otherwise this will remain here simply as a quick reference for yours truly.

In short, CL-IRC1 sucks donkey balls and there's not much I can do about it. Moreover, Common Lisp input/output abstractions are entirely unfit for Unix-based PCs, thusly encouraging some bad coding habits among systems programmers2.

Take the "connect" function for example. As you can see, it doesn't do all that much: it creates a new socket and it juggles it around for a bit, then, assuming we're on SBCL, it sets some socket parameters -- this latter bit was added by yours truly some months ago, after discussion with folks who made this work for their own bots. This is where I would normally insert a lengthy comparison between Python and Common Lisp, strengths and weaknesses and all that, except this has been beaten to death and I don't find it essential to this particular discussion.

As discussed, Stan's logotron has various pieces for detecting when a connection has been abandoned by the server, among which those socket options, but also some timing measurements, as shown in his detect_disconnect.kv.vpatch:

@@ -274,8 +279,15 @@
     while connected:
         try:
             data = sock.recv(Buf_Size)
+            time_last_recv = datetime.now() # Received anything -- reset timer
         except socket.timeout as e:
             logging.debug("Receive timed out")
+            # Determine whether the connection has timed out:
+            since_recv = (datetime.now() - time_last_recv).seconds
+            if since_recv > Discon_TO:
+                logging.info("Exceeded %d seconds of silence " % Discon_TO
+                             + "from server: disconnecting!")
+                deinit_socket()
             continue
         except socket.error as e:
             logging.warning("Receive socket error, disconnecting.")

Now bear with me: in order to adapt CL-IRC to work this way, I would have to dig through read-irc-message; which calls read-protocol-line; which calls read-sequence-until; which, you'll notice if you look carefully, has a "read-fun" defined in its lexical scope. This makes absolutely no sense, there's no proper piece of the "measure time and based on the measurement, decide" type that I can meaningfuly introduce to CL-IRC so that it reinitiates connection when IRC goes down. Yes, I could do it somewhere deeper or shallower down the ladder of abstraction, but there's no proper measure to decide upon the right place to introduce this change, since there's no "right" there in the first place. It's all an ad-hoc mess, precisely like that other CL thing involving network protocols.

I blame mainly Common Lisp for this mess, and more precisely the "Common" part of Common Lisp. From my point of view it's pretty clear that the so-called stream/sequence abstraction does more harm than good, because it obscures the very mechanism that keeps everything together on nowadays' computers, that is, the inescapable Unix layer. Thus as far as I can observe from my own experience, there's no actual "streams" there -- some guys just had too much time on their hands, so they wrote trivial-gray-streams, Usocket, CL-IRC and some other needlessly bloated rabbit holes for the naive programmer to keep their minds occupied.

Thus, IRC implementations don't need the wrappers, interfaces and layers illustrated above; and furthermore, they unneed them, so that they can cleanly use the only true stuff, namely that provided by the operating system. In other words, I can't make any improvements to Feedbot until I get rid of CL-IRC, so I'm sorta contemplating going back to ye olde trivial-irc or rewriting my IRC from scratch, or... I don't know, anything but the current mess.

Post Scriptum: Feedbot connection has been shaky lately, due for the most part to Freenode, which for some reason has my regular IRC clients reporting lags in the tens of milliseconds, while delaying messages from Feedbot for tens of seconds, sometimes up to a couple of minutes or so. Why it does this, and why, of all IRC nicks I keep connected, only to Feedbot, shall remain a mystery for now, at least until I somehow magically figure out the issue from my end. Otherwise if you want to propose ways to deal with this, I'm all ears... well, eyes.


  1. The basis upon which Ircbot, and in particular Feedbot, is written. 

  2. IRC, the protocol, being a piece used for building computer-based systems, it then follows that IRC implementations are systems software. And it's just not just IRC either: there's absolutely no way of writing anything related to "network connections" without taking into account all the peculiarities of TCP

Filed under: computing, lisp.
RSS 2.0 feed. Comment. Send trackback.

5 Responses to “Briefly, on programming IRC bots using Common Lisp”

  1. #1:
    magicmike says:

    If you weren't clueless, you'd spend 1 day and write a full IRC bot in SBCL from scratch, using only built-ins and the FFI. But since you are an idiot, you're always looking how other people did it in order to get a clue.

    And then, because you don't have a clue, you start going sideways into modifying SBCL internals (lol) and/or blaming shitty code for being shitty.

    Get a clue, be an engineer not a coder.

  2. #2:
    spyked says:

    Motherfucker, I didn't and in general I don't read code "because I wanted to get a clue", I read it because I want to find out just how much of a clue the people who wrote it had. And in this particular case, instead of a clean interface to Lunix system calls, I found layers upon layers of reimplementations upon reimplementations of existing abstractions, just because... I don't know, you tell me. Even better, just get the fuck lost already and take your SBCL with you, I don't need it for IRC bots nor anything else.

  3. #3:
    magicmike says:

    > I read it because I want to find out just how much of a clue the people who wrote it had.

    You're not in the position to find what better and smarter people than you did since you're literally clueless. It's like asking Scuba Steve what he thinks about von Neumann. Your opinions on clean interfaces mean zero since you've got absolutely nothing to back them up.

    It's not like I have to stretch to make this argument. Besides your clueless posts that put your ignorance on display for the whole world to see, you did end up wasting part of your life being a busboy for a romanian gypsy peasant that thinks he's king. Hahahahaha.

  4. #4:
    spyked says:

    > Besides your clueless posts that put your ignorance on display for the whole world to see, you did end up wasting part of your life being a busboy for a romanian gypsy peasant that thinks he's king. Hahahahaha.

    Oh, so this is what it was about all along, wasn't it?

    Listen, you: I don't care if or how MP got you butthurt in the past, just get over it already, it's been more than a year since TMSR disbanded.

    That aside, you acultured fuckwits o'er the ocean are the only ones who are showing their ignorance. Just so you know, there never existed in Romania's short history such a thing as a "gypsy peasant". Se aude acolo-n fund la doamna? No one would have a gypsy till the land, for reasons which I "don't have to stretch" to explain. Similarly, kings never had "busboys", those are only a thing in the Soviet shitholes you motherfuckers so happily inhabit.

    I'll say it once more, since you seem to have missed the observation that you're a nobody with access to a HTML form. And guess what: no, mentioning von Neumann in a discussion doesn't automagically make you someone, nor does it lend more weight to your opinions, be they on my writing, my person or anything else. I, "literally clueless" or otherwise, sat and read and documented the piles of shit you people wrote, whereas "you"... mislead kids with empty slogans such as "be an engineer not a coder" and evil notions such as "FFI" being anything other than a well-crafted lie.

    Dude, I never thought I'd say this, you're a couple orders of magnitude stupider than poor ol' Romanians, you get me? And gypsies are smarter than the latter, so I'll take those over you sad lot anytime.

  5. [...] leaving my previous writing on a dire note, I've decided to try out rolling some cleaner shit for future reference; or at the very least I've [...]

Leave a Reply