tbpl
tbpl (TBPL) is a small object-oriented scripting language written around 2006 by the Russian developer known as kmeaw, in which everything is done by sending messages to objects and braces denote first-class blocks. It ran its author's home page and a wiki engine called TikiL, was submitted to 99 Bottles of Beer as release candidate 0.997 on 12 November 2006, and then disappeared: its own site tbpl.info was in other hands by the start of 2008 and no copy of the implementation is known to survive
Created by A developer who signs everything as kmeaw and gives no other name on any of the surviving pages. The 99 Bottles of Beer entry lists the author as kmeaw with the home page kmeaw.com; the TikiL wiki footer reads (c) kmeaw 2006. The same handle is used for a GitHub account created on 11 June 2009, which holds no tbpl repository
tbpl is a small object-oriented scripting language written in 2006 by a
developer who signs their work kmeaw. For a few months it did real work: it
generated its author’s home page, it ran a wiki engine, and - according to a
download link on that home page - it was packaged for Linux and Windows. Then
the domain that documented it lapsed, the home page was rebuilt around something
else, and the language vanished so completely that the two programs quoted on
this page - a thirty-line beer song and a two-line addition - are, as far as can
be established, the entire surviving corpus.
That makes tbpl a useful specimen of a category the language catalogues are full of and rarely admit to: the competent one-person language that was genuinely used, never written about by anyone else, and lost when a single hosting bill went unpaid.
What the record actually contains
Four things survive, and it is worth being precise about them, because everything below is derived from them:
| Source | Date | What it gives |
|---|---|---|
Capture of kmeaw.com | 14 June 2006 | The claim that the page is written in tbpl and uses seven of its own classes; links to the page source, to an XML form of it, and to a distribution archive labelled for Linux (x86/ARM) and Windows |
Capture of www.kmeaw.com/tikil.tbs/data/About | 13 November 2006 | The TikiL wiki front page, the statement that TikiL is written on TBPL, and the wiki’s full table of contents |
| 99-bottles-of-beer.net entry 1324 | submitted 12 November 2006 | A complete thirty-line program, the build string tbpl rc-0.997 20061112, and the author’s contact details |
Captures of kmeaw.com | 29 September 2007 to 8 July 2009 | A terminal transcript of a compiler for a typed dialect, emitting x86 assembly |
Everything else - the reference pages Syntax and Functions, the page
WhatIsTbpl that would have explained the name, the TbplTutorial, the
RealApplications and ConvertedFromC example collections, and whatever
TbplOS was - was on the wiki, was never captured, and is gone. So is
tbpl.info, which the author gave as the language’s information site and which
by January 2008 was serving Russian motoring copy to whoever typed the address.
Even the expansion of the abbreviation is unrecorded; the file extension .tbs
is presumably tbpl script, but that too is an inference.
The language as it can be read off the code
The 99 Bottles program is short enough to reproduce in full, and it is dense with syntax:
*CBottle = CClass new
implements:
{
self 'toString =
{
self bottles > 1
then
"\{self bottles} bottles"
:else self bottles == 1 then
"\{self bottles} bottle"
else
"no more bottles"
};
};
CBottle 'initialize =
{
self 'bottles = 99;
};
*beer = CBottle new;
{
io <<< "\{beer} of beer on the wall, \{beer} of beer.";
io << "Take one down and pass it around, ";
beer bottles -= 1;
io <<< "\{beer} bottles of beer on the wall.";
} while { beer bottles > 0 };
io <<< $(No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.);
Everything is a message send
There is no dot, no arrow and no parenthesised call in the object code.
CClass new sends new to CClass; CBottle new sends new to the class it
produced; beer bottles reads a slot by sending its name; self bottles > 1
sends bottles to self and then > to the result. Juxtaposition is
application, and the receiver comes first. implements: is a keyword message
taking a block - the class body - which is a construction that anyone who has
read Smalltalk will recognise on sight, though nothing in the surviving material
says that is where it came from.
Braces are first-class blocks
The same { ... } construct is the body of toString, the body of
initialize, the body of the loop and the condition of the loop:
{ ...body... } while { beer bottles > 0 };
while here is not a statement keyword parsed by the grammar; it reads as a
message sent to a block, taking another block as its argument. A language in
which the loop construct is an ordinary method on a block object is making a
deliberate design commitment, and tbpl makes it in the only loop it is known to
have executed.
Slot names are quoted, bindings are starred
Two sigils appear. A leading apostrophe names a slot rather than reading it, so
self 'toString = { ... } installs a method and self 'bottles = 99 creates and
sets an instance variable, while the unquoted self bottles fetches one. A
leading asterisk introduces a new binding: *CBottle = ... and *beer = ...
declare, where the later beer bottles -= 1 merely updates. The compound
assignment -= exists.
Conditionals are expressions
The toString method has no return. It is a single
cond then value :else cond then value else value chain whose value is the
value of the method, with :else written as one token joining the arms. The
result is used implicitly: "\{beer}" interpolates the object beer, and the
runtime calls toString on it - which is why the program’s first line reads
"\{beer} of beer on the wall" and prints 99 bottles of beer on the wall.
Strings interpolate, and there is a verbatim literal
"\{expr}" embeds an expression in a double-quoted string. Alongside it,
$( ... ) is a literal that runs to the matching parenthesis and preserves
newlines, used at the end of the program for the two-line final verse. And
output is done with C++-style stream operators on an io object, where <<
writes and <<< writes with a trailing newline - a tidy piece of notation that
does exactly one useful thing more than its model.
The typed dialect
From September 2007 the home page showed something rather different, and it stood there through captures taken in December 2007, twice in 2008 and in July 2009:
$ cat test.tbs
'add (Function Int) = (x + y) lambda (Int x, Int y);
puts add (3, 4);
$ ./main test.tbs > test.s
$ gcc test.s -g -m32
$ ./a.out
7
Three things changed at once. Bindings now carry declared types -
'add (Function Int) - and lambda parameters are typed individually. The
lambda is written postfix, body first: (x + y) lambda (Int x, Int y). And the
tool is a compiler, not an interpreter: it consumes the script and writes an
assembly file, which the transcript hands to gcc with -m32 and runs. Between
the two, ./main prints the whole program back as an S-expression in which
every node is annotated with the type inferred for it, down to the literals
(3) -> Int - the sort of debugging output a person writes when the type
checker is the part they are working on.
The transcript is the only evidence for this dialect. Whether it was a successor to the 2006 interpreter, a branch, or an experiment that was never finished cannot be determined; the version string was never published and no artefact from it has been found.
Running tbpl
You cannot, and this section exists to say so plainly. The distribution archive
advertised in 2006 as tbpl for Linux (x86/ARM) and Windows was never captured
by the Internet Archive, nor was the index.tbs source of the home page, nor
the compiler shown in the 2007 transcript. There is no repository, no package,
no mirror and no Docker image. The thirty-line program can still be read out of
the Internet Archive’s captures of the 99 Bottles of Beer site - the site itself
stopped resolving during 2026 - but nothing anywhere will run it.
That platform list is itself worth a note of caution: it is the wording of a
single download link on the author’s own page in 2006, and no independent
confirmation of it exists. The 2007 transcript’s gcc -m32 is evidence that the
compiled dialect targeted 32-bit x86, and the author’s parallel interest in the
iPAQ hx4700 makes an ARM build plausible, but neither claim can be verified
against a binary that no longer exists.
Where the catalogues go wrong
tbpl appears in language lists as a procedural scripting language from the
2000s. Only the last of those is safe, and it can be sharpened: 2006. The word
procedural does not describe a language whose only surviving program builds a
class, installs a method into it by name, overrides string conversion, and loops
by sending while to a block. The lowercase spelling in those lists is an
artefact too - it is how the 99 Bottles of Beer site rendered the entry, whereas
the author’s own wiki writes TBPL in prose.
The dormant status, though, is exactly right, and unusually easy to date. The information site was gone by January 2008; the last tbpl material on the home page was replaced by December 2009; the author’s GitHub account, created in June 2009 and holding 84 public repositories, contains nothing by that name.
Why it matters
tbpl was not important and never claimed to be. What makes it worth a page is how ordinary its disappearance was, and how much of the design still comes through the wreckage. From two programs and a wiki front page it is possible to establish that this was a message-passing object language with first-class blocks, expression conditionals, string interpolation, slot-naming sigils and a class protocol - and that its author was far enough along to run a public web site on it, write a wiki engine in it, offer a distribution for several targets, and then start again with a typed dialect and a native-code compiler.
Every one of those is a milestone that a hobby language reaches only if someone is serious about it. None of them was enough to survive a lapsed domain registration. The languages that endure are not always the better ones; they are the ones that ended up somewhere - a distribution, a repository, a book - that outlived their author’s interest in paying for hosting. tbpl ended up on a page about beer, and that is the only reason there is anything left to read.
Timeline
Notable Uses & Legacy
kmeaw.com (2006)
The author's home page was a tbpl program. The June 2006 version says outright that the page the reader is looking at is written in the language and uses seven classes of its own, and offers both the .tbs source and an XML rendering of it for inspection. It is the only documented case of tbpl being used to serve a live public web site
TikiL wiki engine
A wiki engine written in tbpl and served from URLs under /tikil.tbs/, used to host the author's own documentation - the tbpl syntax and function reference, a tbpl tutorial, worked examples, and separate C and x86 assembly-language course material with editable pages and a create-article form. It is the largest tbpl application on record, and only its front page survives
99 Bottles of Beer, entry 1324
The submission that put the language on the 99 Bottles of Beer site in November 2006 and, through it, into the language catalogues. Because the entry preserves both a complete working program and the build string rc-0.997 20061112, it is now the primary source for what tbpl code actually looked like