From Esolang
Jump to navigation Jump to search

Fact is a programming language created by User:Javawizard, Schrottplatz and MrDudle for JZBot, an IRC bot. Assuming an interpreter with no memory constraints, Fact is a turing-complete language (proof will come soon in the form of a BF interpreter written in Fact that Javawizard is working on).

Fact is esoteric primarily because, since every character (bar some small exceptions) is significant to how the program functions, most fact programs tend to be written all on the same line. Indeed, only recently was it possible to write multi-line programs; versions of the interpreter up until around October 2009 only allowed programs that contained no newlines. The "99 bottles of pop" example further down demonstrates how unreadable it starts to get. Additionally, Fact has only one datatype: text.


When JZBot was created, it was a simple factoid-based IRC bot, much like Infobot. Superops (those with permission to perform various tasks on the bot, such as shutting it down) could create factoids, which were named pieces of text. When someone sent "~name" to a channel, the bot would send the text of the factoid called "name" to the channel, or issue a warning if there was no such factoid.

This was great, as things went, until three additional pieces of functionality were requested by various users: the ability to send CTCP actions with the bot (as if the message had been prefixed with "/me"), the ability to invoke a factoid with "arguments" which could then be embedded within the factoid's text, and the ability to choose the first of several arguments (including a pseudo-argument representing the user that invoked the factoid) that was not empty.

The first problem was solved by way of running all factoids that start with "<ACTION>" as a CTCP action. The second problem was solved by breaking up all of the text after the factoid's name into "variables" (the precursor to Fact's concept of local variables), which could be included into the text of a factoid by surrounding the name of a variable with "%" characters. The third problem was solved by adding a special syntax, "{{firstvar||<varname>||%var1%||%var2%||...}}" (which still exists as the firstvar function), that the bot would read. The bot would search for all indexes of "{{firstvar||" in the factoid text, split all text between that and the next "}}" around the "||" characters embedded within it, and set the variable accordingly (look at Fact's firstvar function for a description of what this did).

Soon after, the ifeqv function (which is no longer present in Fact but, for {{ifeqv||<1>||<2>||<3>||<4>||<5>}}, is functionally equivalent to "{{lset||<1>||{{ifeq||<2>||<3>||<4>||<5>}}}}") was added so that a factoid called "insult" could be created that insulted a named person, unless that person's name was equal to any of the JZBot authors, in which case the person running the factoid would be insulted.

A "random" function (which, like firstvar, was carried over into Fact itself) was soon added to enhance the insult factoid with the ability to randomly pick between a number of insults.

However, due to the fact that the bot would simply search for the start sequence (such as "{{firstvar||") for each function and then parse everything until the next end sequence ("}}") it matched, it wasn't possible to nest function calls within each other. Due primarily to this limitation, the factoid parser was re-written to allow for nested function calls. This was the first version of Fact.

At this time, there were 4 functions: firstvar, random, ifeq, and ifeqv. Others were soon added, resulting in more complex functionality available to factoids. Today, Fact has enough functions (as of December 23, 2009, there are 163 functions) that it is turing-complete.

The language

Fact has only one datatype: text. An individual piece of text is referred to as a string. Characters within a Fact program that do not contain any of Fact's special sequences (which are "{{", "||", "}}", "%", and "\") constitute a string. An interesting property of this (and, in fact, one of the primary design goals) is that a program that does not contain any special sequences is a quine.

More to come on the language itself (or you can read the language reference at the tail end of the page and edit this section yourself).


The official Fact interpreter is part of the JZBot codebase, and currently only works as part of JZBot itself. JZBot is available here. Javawizard hopes at some future point to export the interpreter so that it can be run as a standalone program.

You can join irc.freenode.net channel ##jzbot to see JZBot and Fact in action. Marlen_Jackson is the official JZBot.


Newlines in these examples are added to prevent line-wrapping. The JZBot Fact interpreter ignores actual newline characters (for versions of the interpreter released after October 2009), so they have no effect on the program's operation.

Hello, world! -- pointlessly simple

Hello, world!

99 bottles of pop -- This correctly handles 1 (IE it says "1 bottle of pop" instead of "1 bottles of pop"), and it also puts the whole thing on one line

{{for||99||1||v||%v% bottle{{ifneq||%v%||1||s}} of pop on the wall, %v% bottle{{ifneq||%v%||1||s}} of pop. 
Take {{ifeq||%v%||1||it||one}} down, pass it around, {{eval||%v%-1}} bottle{{ifneq||{{eval||%v%-1}}||1||s}} of pop on the wall.|| }}

External resources