This is something I wanted to rant about for a while: event loops in programming.
This post is specifically talking about programming languages that don't have their own built-in async model, and instead left it up to the community to create their own event loop modules instead. And how most of those modules don't get along well with the others.
Over the last couple months I've been slowly working on rewriting RiveScript in yet another programming language: Google's Go language! It's also my first project in Go, which is what tends to be the case (rewriting RiveScript in Java and Python were my first projects in those languages, too).
But this is the last time I'm going to be rewriting RiveScript from scratch.
For some historical background, the first RiveScript implementation was written in Perl, and I designed it to be one big monolithic file (
RiveScript.pm), because then I could tell noobs that they can update to a new version of RiveScript in their bots by just dropping in a new file to replace the old one, and avoid overwhelming them with the complexity of doing a CPAN installation (especially if they're generally new to Perl as well, and all they really wanna do is just run a chatbot.)
I've just spent pretty much the whole day redoing the website for RiveScript.com, and I think it looks pretty nice.
RiveScript.com was the final website on my server that was still running on my legacy PerlSiikir CMS, and it's been on my to-do list for a while to get it migrated over to my new Python CMS, Rophako like what Kirsle.net is currently running on. The old Perl code was clunky and ugly and memory-leaky, and now I'll be at ease if I ever need to migrate to a new web server, as my Python web apps are extremely quick to get up-and-running, whereas it was an hours-long ordeal to get PerlSiikir to run.
So, the bulk of the work actually needed for RiveScript.com was purely front-end. I revamped the whole web design to use Twitter Bootstrap and make it look all hip and edgy like how all the other small software project websites are these days.
Besides the programming language on the back-end, I had other reasons for why I wanted to simplify RiveScript.com: I don't have the motivation or energy to do as much with that site as I did previously.
I used to run a YaBB Forum on RiveScript.com, but it wasn't extremely active and it was getting hit by too many spam bots, so several months ago I shut that down and linked to the RiveScript forum at Chatbots.org.
More recently I had programmed a chatbot hosting service that was on RiveScript.com, but that wasn't very popular either. I know nobody was using it because it had been broken for months and I hadn't heard any complaints. A couple months ago I sunsetted that feature by turning off new site registrations and removing some references to the feature. And now that's officially gone! If you actually had a bot hosted there, contact me and I can get you your bot's reply files back.
So, the new site is simple and minimalistic and is just about the RiveScript language itself. It was an ordeal rewriting all of the pages from scratch (well, most of them) but now that it's done, the site should be very low-maintenance for me.
And, the front-end pages for the new site are also open source, FWIW.
In an older blog post I mentioned getting Alicebot Program V, a Perl implementation of an Alice AIML bot, up and running on a modern version of Perl, but I didn't go into any details on what I actually did to get this to work (which wasn't very nice of me ).
Unfortunately for me I also didn't even write down any notes for myself, so I had to figure it out again, myself, from scratch. Which I decided to do, only this time I wrote down some notes, and published a new, updated version of Program V which you can check out on GitHub -- or for the lazy, get a zipped release of Program V 0.09.
This blog post is about what I needed to do to get Program V up and running, some of which is also outlined in
UpdateNotes.md on the GitHub repo.
So, first of all, Program V was programmed for Perl version 5.6, which is ancient; by the time I had discovered the existence of Program V, the current version of Perl was 5.8, and already, Program V would not run out-of-the-box on Perl 5.8; and I was a newbie back then and had no experience to draw from to figure out how to get Program V to work for me. I wanted to use Perl to make chatbots, and Program V was the only AIML implementation around, but I couldn't use it, and it eventually led me to just create my own chatbot language to replace AIML for me -- RiveScript.
The differences between Perl 5.6 and all newer versions are pretty significant and some things have changed, and that's the basic background on why Program V was hard to get to work.
So the first thing I needed was to install the Perl modules
Unicode::Map8 - I learned this the hard way by trying to run
build.pl and getting missing module errors, but the README also mentioned I needed these things. And then I got an error message that probably looks familiar to a lot of people who've tried (and failed) with Program V:
[~/g/programv]$ perl build.pl Constant subroutine AIML::Common::LOCK_SH redefined at lib/AIML/Common.pm line 52. Prototype mismatch: sub AIML::Common::LOCK_SH () vs none at lib/AIML/Common.pm line 52. Constant subroutine AIML::Common::LOCK_EX redefined at lib/AIML/Common.pm line 53. Prototype mismatch: sub AIML::Common::LOCK_EX () vs none at lib/AIML/Common.pm line 53. Constant subroutine AIML::Common::LOCK_NB redefined at lib/AIML/Common.pm line 54. Prototype mismatch: sub AIML::Common::LOCK_NB () vs none at lib/AIML/Common.pm line 54. Constant subroutine AIML::Common::LOCK_UN redefined at lib/AIML/Common.pm line 55. Prototype mismatch: sub AIML::Common::LOCK_UN () vs none at lib/AIML/Common.pm line 55. Died at lib/AIML/Unicode.pm line 102. Compilation failed in require at lib/AIML/Common.pm line 109. BEGIN failed--compilation aborted at lib/AIML/Common.pm line 109. Compilation failed in require at build.pl line 32. BEGIN failed--compilation aborted at build.pl line 32.
The most interesting line to me was when it said
Died at lib/AIML/Unicode.pm line 102. without any error message (looks like a
die; statement in Perl with no message), so I looked at this line of this file, and it was doing this:
my $changer = do ( $pkg ) or die;
So I debugged it (read: added a
print "$pkg\n"; above that line) and found it was trying to import
unicode/To/Upper.pl which was nowhere to be found. On my Linux system I ran a
locate Upper.pl command, and found that a similarly named file existed at
/usr/share/perl5/unicore/To/Upper.pl - the key difference is that "unicode" is spelled "unicore".
There were 3 lines of code in
AIML::Unicode that reference files like this and I changed all three to point to the "unicore" versions - fixed it!
build.pl would now make some progress.
It then complained about a couple of the AIML files containing illegal characters in their
<pattern> tags. No big deal, went in and fixed them.
build.pl runs successfully now! And then I ran
shell.pl and was dropped into an interactive chat session with an Alice bot.
As for those
AIML::Common::LOCK_SH warnings: I have to assume that in Perl 5.6, file locking (
flock) was either a new feature or not widely implemented, and the code was trying to do a few error checks (in a Perl 5.6 style way) and if
flock isn't found to be available, it would shim those constants itself. But,
flock is available, but the error checks were still going off, so
AIML::Common was overriding the constants. So, I just fixed the error checks and problem solved.
So once I got it working, I published the updated version of Program V on my GitHub account for others to check it out.
This doesn't mean Program V is actively maintained again. It was abandoned by its author in 2002 and hasn't been able to run on modern Perl ever since; I simply updated it so it works again. If that inspires you, feel free to fork it and maintain it on your own - it was released by its author under the same terms as Perl itself.