STORY

The 35-Year Story of chat.pl and chat2.pl

  • The 35-Year Story of chat.pl and chat2.pl

  • On June 16, 1991 (91/06/16), I posted a 350-line Perl 4 library called chat2.pl (V2.01.alpha.7) to the comp.lang.perl Usenet newsgroup. That single Usenet post went on an extraordinary 35-year journey: silently bundled by Larry Wall as the only code I ever wrote that shipped in the core Perl distribution, containing a tongue-in-cheek hardwired socket constant comment that was invalidated 60 days later by Linus Torvalds announcing Linux, powering the underlying transport engine that bootstrapped CPAN, being deleted from Perl core in 2000 at my own request ("Delete chat2 as requested by Randal"), becoming a Polish .pl domain conference lightning talk punchline (http://chat2.pl), and coming full circle in 2026 in my work governing AI "chat" coding agents.
  • 1. Origin: Scratching an expect Itch in Pure Perl 4 (June 1991)

    • In 1988, John Ousterhout created Tcl/Tk, and in 1990, Don Libes built expect on top of Tcl so Unix scripts could interact with conversational command-line programs (passwd, telnet, ftp, fsck) over pseudo-terminals (PTYs) and sockets. Without Ousterhout, we would not have had tcl/tk or expect—both essential early Unix tools.
    • I wanted an expect-like pattern-matching state machine directly inside Perl 4 that worked cleanly across both TCP sockets and pseudo-terminals (PTYs) without requiring users to install Tcl and expect. Rather than naming it expect.pl—both because I did not want to imply a 1-to-1 API mapping to Libes's expect and because there was already an expect.pl floating around—I named my library chat.pl and evolved it into chat2.pl (## chat.pl: chat with a server / ## V2.01.alpha.7 91/06/16 / ## Randal L. Schwartz), posting it to comp.lang.perl because it was solving real automation problems for me.
    • Technical Highlights of chat2.pl (91/06/16)

      • Guarded Pattern-Action State Machines with Explicit 'TIMEOUT' and 'EOF' Branches: chat'expect took a timeout and pairs of regex patterns and action bodies, plus dedicated 'TIMEOUT' and 'EOF' failure guards if a subprocess hung or exited unexpectedly.
      • Dynamic On-the-Fly Subroutine JIT Compilation & Memoization: Rather than re-interpreting pattern lists on every select() wake-up, chat'expect dynamically generated a custom Perl subroutine (expectloop000000, expectloop000001, ...) via eval $cases and memoized it by caller and argument list ($expectsubname{$caller,@}).
      • Dynamic Typeglob Handle Generation (chatsymbol000000): Because Perl 4 did not yet have lexical filehandles or object references, chat2.pl used magic string auto-increment on $next = "chatsymbol000000" and assigned *S = ++$next to return unique symbol-table handles for each open TCP socket or PTY subprocess.
  • 2. The h2ph Trade-Off and the 1991 "Linux" Prophecy

    • In Perl 4 (prior to Perl 5's compiled XS use Socket; module), accessing C header constants like AFINET, SOCKSTREAM, and TIOCNOTTY from /usr/include/sys/socket.h and sys/ioctl.h required loading .ph Perl header files (require 'sys/socket.ph'). Those .ph files only existed if the local system administrator had manually run the h2ph tool as root after installing Perl—and on a huge fraction of 1991 Unix systems, sysadmins either skipped running h2ph or watched h2ph choke on complex vendor C preprocessor macros.
    • To make chat2.pl work with zero installation dependencies straight off Usenet, I deliberately hardwired the standard BSD socket and ioctl constants (2, 1, 6) (AFINET = 2, SOCKSTREAM = 1, IPPROTO_TCP = 6) and 0x20007471 (TIOCNOTTY), leaving a tongue-in-cheek comment on lines 32–34:
      # XXX hardwired $AFSOCKET, $SOCKSTREAM, 'tcp'
      # but who the heck would change these anyway? (:-)
    • Sixty days later (August 25, 1991), Linus Torvalds announced Linux on comp.os.minix—"a different sort of Unix from a new origin." Between Linux (TIOCNOTTY = 0x5422) and System V Release 4 / Solaris (SOCK_STREAM = 2 instead of 1), those "unchangeable" constants changed right out from under chat2.pl!
  • 3. Silent Inclusion by Larry Wall & Bootstrapping CPAN

    • Without my knowledge, [Person/Larry Wall]] scooped my V2.01.alpha.7 posting off Usenet and bundled it directly into the Perl 4 standard library (lib/chat2.pl) on November 5, 1991 (perl 4.0 patch 12, commit [11aea36008). When the release came out and I saw my alpha.7 Usenet script published inside the official Perl core distribution, I was completely shocked!
    • Ironically, chat2.pl became the only piece of Perl code I ever wrote that shipped inside the core Perl distribution—freezing my V2.01.alpha.7 header, # but who the heck would change these anyway? (:-), and # Recursive invocations are not thought through, and may work only accidentally. :-) onto every Unix machine in the world.
    • Because chat2.pl was now guaranteed to be present in /usr/local/lib/perl/chat2.pl on every Perl installation worldwide:
      • Lee McLoughlin at Imperial College London built ftp.pl and the mirror package on top of chat2.pl.
      • Jarkko Hietaniemi, Andreas König, and the early Perl community used mirror (ftp.pl -> chat2.pl) to synchronize and bootstrap the global CPAN mirror network starting in 1995.
      • Thus, a 350-line alpha.7 script posted to Usenet became the underlying transport engine that bootstrapped CPAN—the ancestor of every modern language package registry (npm, PyPI, RubyGems, Cargo, pub.dev).
  • 4. Nine Years in Core & "Delete chat2 as requested by Randal" (1991–2000)

    • The Perl/perl5 git commit history for lib/chat2.pl records its entire nine-year lifecycle in core:
      • 11aea36008 (November 5, 1991 — Larry Wall): Imported V2.01.alpha.7 into perl 4.0 patch 12.
      • 68decaef0a (June 8, 1992 — Larry Wall): Added $PID{$next} tracking and waitpid($pid, 0) on close in perl 4.0 patch 22.
      • f97f1ee016 (March 17, 1996 — Perl 5 Porters): Attempted to fix the Linux/SVR4 socket constant collision by adding an unconditional require 'sys/socket.ph'; at the top of lib/chat2.pl while moving # but who the heck would change these anyway? (:-) into the else branch—which promptly broke chat2.pl on every system where the sysadmin had not run h2ph!
      • a6d7165678 (July 26, 1999 — Gurusamy Sarathy): Added a deprecation warning at the top of lib/chat2.pl advising users not to use it as an example of modern Perl programming techniques.
      • 50f338d87d (May 15, 2000 — Author: [Person/Randal Schwartz]], Committer: Jarkko Hietaniemi): During a perl5-porters discussion (Subject: Re: perlfaq8 coyness, Message-ID: <m166sfl0r9.fsf@halfdome.holdit.com>), I asked for chat2.pl to finally be put out of its misery. Jarkko removed it in commit [50f338d87d with the commit message: "Delete chat2 as requested by Randal."
  • 5. The http://chat2.pl Polish Domain Easter Egg & The 2026 Second Act

    • The 15-Year .pl Domain Quest & 2016 Lightning Talk:
      • On October 8, 2001, I sent an email titled "an odd request" to Poland's .pl country-code TLD registry (info@dns.pl), writing: "I'm the author of many Perl-related things. One in particular is the now obsolete 'chat2.pl' that was included with all copies of Perl4, and continues to haunt me even though it's never been supported. My friends agree that it'd be hilarious if I could get 'chat2.pl' as a domain name, and of course, that's where you come in."
      • After waiting nearly fifteen years for .pl registration rules to open up, I finally registered http://chat2.pl via Hover on March 7, 2016, pointed it straight to the original Perl/perl5@11aea36008 commit on GitHub, and emailed Larry Wall on March 16, 2016 (Subject: chat2.pl): "chat2.pl just got real: http://chat2.pl — Finally, after waiting 20 years for that domain name."
      • In June 2016, I delivered the lightning talk "The legacy of chat2.pl" at YAPC::NA 2016 (The Perl Conference) in Orlando, Florida—unveiling live on stage that http://chat2.pl resolved to the 1991 core commit.
    • 1991–1994 Tools Built on chat2.pl:
      • Beyond powering Lee McLoughlin's ftp.pl and mirror for CPAN, I used chat2.pl in my own early 1990s networking and aviation tools, including ftpr (91/08/16, a recursive regex-driven FTP mirror script), mypost (91/10/22, a single-process binary splitter, uuencoder, and NNTP poster), a Contel DUAT aviation weather briefing client (1993, fetching pre-flight weather briefings for Hillsboro Airport HIO over port 23), and nclip (1994, an NNTP keyword-clipping daemon modeled after Larry Wall's clip).
    • The 35-Year Arc to AI Agent Orchestration (2026): Thirty-five years after I named a guarded interactive subprocess supervisor chat2.pl, the software industry adopted LLM "chat" interfaces—and repeated every mistake expect and chat2.pl were invented to solve (running conversational streams without invariant guards, timeouts, or explicit failure branches, while hardwiring happy-path assumptions like # but who the heck would change these anyway?). In October 2026, my Synthetic Scars and Smalltalk-80 StateGraph architecture brought the guarded-pipe state-machine philosophy of chat2.pl full circle to govern autonomous AI coding agents.
These facts are as Randal recalls them, but much time has passed for most of this. If you find a factual error, please email realmerlyn@gmail.com.