LOLCODE Tutorial: A programming language for cat lovers

The festive season is upon us, and I think it’s the perfect time to have some fun! Today, I would like to give the gift of a LOLCODE tutorial which explains how to get started with this esoteric language for feline fanatics. Basically, LOLCODE language emerged as a funny experiment and it’s based on an Internet meme called “lolcat”. This meme is an image macro that usually features a cat and some funny text. The text often contains intentional grammar mistakes — it is called “lolspeak” (sometimes, “catspeak”). Some popular lolcats include Grumpy Cat, Longcat, and Serious Cat.

So, if lolspeak exists, lolcode should too, right? You betcha! Effectively, LOLCODE was inspired by catspeak and was introduced by Adam Lindsay in 2007. This language does not have a clear definition but still it is possible to write relatively complex programs using it. Therefore, in this post I will guide you through this language and show various usage examples. One thing to note, though: this language was created for fun only and it is by no means ready for production use. Still, it is even possible to create a simple webserver with it

The source code can be found on GitHub.

 

Installing LOLCODE interpreter

So, to get started we will need an interpreter to run our scripts. In this tutorial we are going to use lci — a LOLCODE interpreter written in C language. First of all, download the latest release from GitHub and unpack the archive. Then, the steps will vary depending on your operating system.

Installing LOLCODE on Linux and Mac

To install the interpreter on Linux or Mac systems, you’ll need CMake and Python 2.7+. CMake should already be present on Linux, and Python is usually available on all *nix systems.

Then simply run the following command:

./install.py --prefix="/home/username/opt"

This is going to install lci in the /home/username/opt directory. That’s it!

Installing LOLCODE on Windows

Unfortunately, Windows does not provide the required build tools out of the box, so you will need to do the following:

  1. Install Python 2.7+ and make sure it is added to your PATH.
  2. Install MSYS2 by following instructions on the official website.
  3. Open msys2.exe and run the following command: pacman -S base-devel msys2-devel cmake to install all the necessary tools.
  4. Change directory to the lci folder and run cmake . and then make && make install.

Alternatively, you can simply use Repl.it online IDE which supports LOLCODE as well.

LOLCODE basics

The basics of LOLCODE are nicely summarized in the official documentation. In this section we are going to discuss the most important concepts and also explore some examples.

Creating and running the files

Programs written in LOLCODE should have a .lol extension. Each file should be opened with a HAI instruction followed by the language number (we are going to be using version 1.2). After this instruction you can write the actual code.

The file should be closed with a KTHXBYE command. Here’s an example:

HAI 1.2

...your code here...

KTHXBYE

To run a program, use the following command:

lci /user/path/my_script.lol

On Windows, you’ll need to run this command from the MSYS2 terminal.

Comments

To add a single-line comment, use the BTW keyword:

HAI 1.2

BTW your comment can be added here!

KTHXBYE

Multi-line comments are wrapped with OBTW and TLDR keywords:

HAI 1.2

OBTW I'm writing a comment here
and it goes here as well
TLDR

KTHXBYE

Working with variables

To work with a variable, you have to declare it first using the I HAS A statement followed by the name of your variable. Then you can assign some value to it by employing the YOUR_VARIABLE R YOUR_VALUE construct. For instance:

HAI 1.2
  I HAS A my_num
  
  my_num R 3  BTW my_num is now equal to 3!
KTHXBYE

In the above example we’re creating a new variable called my_num and then assigning a value of 3 to it. Note that we’ve also added indentation for the main code block, but this is not required and does not have any special significance to the interpreter.

You can declare a variable and assign a value to it in one go by adding ITZ YOUR_VALUE after the declaration:

HAI 1.2
  I HAS A my_num ITZ 3
KTHXBYE

Variables can contain data of the following types:

  • String (YARN type): for example, "cat", "this is a string", "" (empty string). Note that strings support interpolation: "My name iz :{NAME} and age iz :{AGE}".
  • Number (NUMBR type): for example, 42 or 9000.
  • Float (NUMBAR type): for example, 42.0 or 3.14.
  • Boolean (TROOF type): WIN (which means “true”) and FAIL (“false”).

If a variable does not have any value upon declaration, it is considered to be untyped (NOOB type). Finally, note that LOLCODE uses dynamic typing; therefore, you don’t have to provide types manually.

Naming your variables

In LOLCODE, the variable naming guidelines are quite simple:

  • The variable name must begin with a letter.
  • The variable name can contain letters, numbers, or underscores.
  • You cannot use dashes or any other special characters when naming your variables.
  • You can use letters in lowercase or uppercase, or a combination of both. Remember, in any case, that variable names are case sensitive.

Variables scope

Also note that in LOLCODE there are no global variables. The variables are either local to the main block of your program, to the current function, or to the cycle. Finally, you cannot access a variable before its declaration.

Using operators

Next, let’s talk about the operators LOLCODE supports. At first, operators may seem awkward because they are written in the prefix format, for example:

SUM OF 1 AN 2 BTW it simply means 1 + 2

The AN keyword is not required when using unary operators. Now let’s take a look at some of the operators LOLCODE has to offer.

Mathematical operators

  • SUM OF — addition.
  • DIFF OF — subtraction.
  • PRODUKT OF — multiplication.
  • QUOSHUNT OF — division.
  • MOD OF — integer division.
  • BIGGR OF — maximum of two numbers.
  • SMALLR OF — minimum of two numbers.

Note that if both arguments are integers (NUMBR), then the result will also be an integer. If one of the numbers is a float (NUMBAR) though, then the result will be a float as well. Finally, the interpreter will try to automatically cast your arguments to numbers, thus the following program is correct:

HAI 1.2
  I HAS A my_num ITZ 3
  
  QUOSHUNT OF my_num AN "2"
KTHXBYE

If the argument cannot be cast, an error will be raised.

Some practice

Let’s write a small program to swap two variable values (represented as integers) without using the third variable. The algorithm is quite straightforward:

  • We have two variables VAR_A and VAR_B.
  • First, we calculate the sum of the two values and store it in the first variable VAR_A.
  • Then, the new value of VAR_B equals VAR_A minus the old value of VAR_B.
  • Finally, the new value of VAR_A is calculated as VAR_A - VAR_B.

Let’s implement the above logic with LOLCODE:

HAI 1.2
  I HAS A VAR_A ITZ 5
  I HAS A VAR_B ITZ 10
  
  VAR_A R SUM OF VAR_A AN VAR_B  BTW 15

  VAR_B R DIFF OF VAR_A AN VAR_B  BTW 5
  
  VAR_A R DIFF OF VAR_A AN VAR_B  BTW 10
  
  VISIBLE "VAR_A: " VAR_A
  VISIBLE "VAR_B: " VAR_B
KTHXBYE

VISIBLE outputs the given text to the terminal. We will discuss this operator in more detail later.

Nice!

Boolean operators

Next, let’s take a look at the boolean operators:

  • NOT — unary negation.
  • BOTH OF — “and”.
  • EITHER OF — “or”.
  • WON OF — “xor”.
  • ALL OF — “and” but with an infinite arity (effectively meaning you can provide as many arguments as needed).
  • ANY OF — “or” with an infinite arity.

Please note that when using an operator with an infinite arity, you have to provide the MKAY keyword at the end of the statement:

ALL OF arg1 AN arg2 AN arg3 MKAY
ANY OF arg1 AN arg2 AN arg3 MKAY

Comparison operators

To compare two values, use one of the following operators:

  • BOTH SAEM==.
  • DIFFRINT!=.

Problem is, there are no operators like “greater than” or “less than”, so you will have to use the following idiom:

HAI 1.2
  I HAS A arg1 ITZ 5
  I HAS A arg2 ITZ 6
  
  
  BOTH SAEM arg1 AN BIGGR OF arg1 AN arg2  BTW arg1 >= arg2
  DIFFRINT arg1 AN BIGGR OF arg1 AN arg2   BTW arg1 < arg2
KTHXBYE

The idea is that first you find the maximum (or a minimum) number and then compare the result with the first argument. More information can be found in the official docs.

Concatenation

To perform string concatenation, use the SMOOSH operator. It has an infinite arity:

HAI 1.2
  VISIBLE SMOOSH "lol " AN "cat " AN "rulez!" MKAY  BTW this will produce "lol cat rulez!"
KTHXBYE

Type casting

Finally, let’s see how to explicitly cast types. In order to do that, use the MAEK operator: MAEK YOUR_EXPRESSION A TYPE. Note that here we should use the A keyword, not AN. The TYPE can have one of the four values listed above (for instance, TROOF).

HAI 1.2
  I HAS A my_num ITZ 42
  
  MAEK my_num A YARN
KTHXBYE

In the example above we’re converting the integer 42 to a string (YARN).

Also, you can recast a variable using the MY_VARIABLE IS NOW A TYPE statement, like so:

my_num IS NOW A YARN

Okay, so we have covered the basics of LOLCODE, now let’s discuss slightly more advanced concepts.

Working with input and output

Output

So, to print something to the STDOUT (standard output, which is effectively your terminal), you would use a VISIBLE operator. It has an infinite arity and does not have to be closed with MKAY:

HAI 1.2
  I HAS A name ITZ "longcat"
  
  VISIBLE "my " "name iz " name " and I'm long"
  VISIBLE "nice to meet " "ya"
KTHXBYE

The output of the program above will be:

my name iz longcat and I'm long
nice to meet ya

The VISIBLE operator converts all arguments to YARN (string) automatically. It also adds a carriage return character \n to the end of the string but you can suppress it by providing a ! symbol at the end of the statement:

HAI 1.2
  I HAS A name ITZ "longcat"
  
  VISIBLE "My " "name iz " name " and I'm long."!  BTW note that I've added a ! symbol here
  VISIBLE " Nice to meet " "ya."
KTHXBYE

In this case you’ll see the following output:

My name iz longcat and I'm long. Nice to meet ya.

Input

To get an input from the user, utilize the GIMMEH operator followed by a variable name:

HAI 1.2
  I HAS A name
  
  VISIBLE "Plz enter yer name:"
  GIMMEH name
  
  VISIBLE "Hey, " name
KTHXBYE

Please note that GIMMEH always converts the entered value to YARN.

For instance, we can create a program to convert kilometers to miles. One mile is roughly 1.6 kilometers, which means we have to perform a simple division:

HAI 1.2
  I HAS A KILOMETERS
  I HAS A MILES

  VISIBLE "Plz enter number in kilometers:"
  GIMMEH KILOMETERS
  KILOMETERS IS NOW A NUMBAR

  MILES R QUOSHUNT OF KILOMETERS AN 1.6

  VISIBLE "Yer number of miles iz " MILES
KTHXBYE

So, this script works in the following way:

  • We ask the user to enter a number in kilometers.
  • Next, we have to convert this value to NUMBAR (float) because initially its type is  YARN.
  • After that, calculate the number of miles which equals to kilometers divided by 1.6.
  • Finally, output the result to the screen.

Conditionals

Now we’ll look at how to create conditional statements. The overall approach is quite simple. You start by creating an expression and then providing an O RLY? statement on the next line:

YOUR_EXPRESSION
O RLY?

Do note, though, that O RLY? can be provided on the same line. In this case you have to add a comma after the expression:

YOUR_EXPRESSION, O RLY?

After that, provide YA RLY (true branch) and NO WAI (false branch) statements. Finally, close the code block with OIC:

YOUR_EXPRESSION, O RLY?
  YA RLY
    BTW true branch goes here
  NO WAI
    BTW false branch goes here
OIC

Additionally, you can provide an “else-if” branch which is written as MEBBE followed by an expression:

YOUR_EXPRESSION, O RLY?
  YA RLY
    BTW true branch goes here
  MEBBE ANOTHER_EXPRESSION
    BTW else-if goes here
  NO WAI
    BTW false branch goes here
OIC

Case statements

Apart from “if-else” logic, LOLCODE also supports case statements. They start with an expression followed by a WTF? statement:

EXPRESSION, WTF?

After that, you can provide as many comparison blocks as needed, each starting with an OMG keyword. Please note that the comparison block must be a unique literal (the number of literals is unlimited). There is also the option to provide an OMGWTF statement acting as a fallback. Finally, close the statement with the OIC keyword:

EXPRESSION, WTF?
  OMG CONDITION1
    BTW the first block goes here
  OMG CONDITION2
    BTW the second block goes here
  OMG CONDITION3
    BTW the third block goes here
  OMGWTF
    BTW the fallback goes here
OIC

You can also provide a GTFO statement inside any of the OMG blocks, which immediately exits the current WTF? statement:

EXPR, WTF?
  OMG COND1
    VISIBLE "COND1"
    GTFO  BTW this statement means "immediately exit the current WTF? block"
  OMG COND2
    VISIBLE "COND2"
  OMG COND3
    VISIBLE "COND3"
OIC

Loops

Infinite loops

Now, let’s see how to create loops with LOLCODE. To create a simple loop, use the below code:

IM IN YR loop_label
  BTW this is the body of the loop
  BTW this loop will go on forever until stopped explicitly
IM OUTTA YR loop_label

loop_label simply marks the start and the end of the loop and is not used inside the loop itself. Note that in the example above we’ve created an endless loop because it does not have any exit conditions or explicit exit statements. To exit the loop, use GTFO:

IM IN YR loop_label
  BTW this is the body of the loop
  BTW this loop will go on forever until stopped explicitly
  
  GTFO  BTW this statement exits from the loop
IM OUTTA YR loop_label

While loops

However, it is also possible to create “while” or “until” loops with slightly more complex code:

IM IN YR cycle ACTION YR VARIABLE WILE EXPRESSION
  BTW this loop will run while the given EXPRESSION is true
IM OUTTA YR cycle

This is a “while” (WILE) loop that will run while the given expression is true (WIN). A couple of things to note:

  • The ACTION can be any unary function, as well as UPPIN (increment the given VARIABLE by 1 on each iteration) or NERFIN (decrement the given VARIABLE by 1).
  • The VARIABLE is temporary and local to the loop. It should not be declared explicitly.
  • You can utilize the VARIABLE inside the expression.

For example, let’s create a WILE loop that has three iterations and increments the temporary variable by 1 on each iteration:

HAI 1.2

IM IN YR cycle UPPIN YR temp WILE BOTH SAEM temp AN SMALLR OF temp AN 2
  VISIBLE temp
IM OUTTA YR cycle

KTHXBYE

The output is:

0
1
2

In this example, we iterate temp by 1 (initially its value is 0) on each iteration. The loop runs while temp is less than or equal to 2. Once this condition becomes false (FAIL), we exit the loop.

Until loops

So, you can create until loops in pretty much the same way as while loops. The only difference is that you need to say TIL, not WILE:

HAI 1.2

IM IN YR cycle UPPIN YR temp TIL BOTH SAEM temp AN BIGGR OF temp AN 2
  VISIBLE temp
IM OUTTA YR cycle

KTHXBYE

In this instance, the loops run until temp is greater or equal to 2.

Functions

The final topic I’d like to discuss is the use of functions in LOLCODE.

Defining functions and returning values

The function definition starts with a HOW IZ I statement followed by a function name. Then, you can provide an optional list of arguments by saying YR ARGUMENT1 AN YR ARGUMENT 2 .... Then provide the body of your function and finally close the definition with IF U SAY SO:

HOW IZ I CALCULATE_CIRCLE_PERIMETER YR RADIUS
  VISIBLE PRODUKT OF 6.28 AN RADIUS
IF U SAY SO

In this example, we’re creating a function to calculate the circle perimeter using the formula 2 * PI * Radius. 2 * Pi is roughly 6.28, therefore we take this number and multiply it by radius.

To return a value, use FOUND YR EXPRESSION. To return with no value (NOOB type), say GTFO:

HAI 1.2

HOW IZ I CALCULATE_CIRCLE_PERIMETER_FOR YR RADIUS
  FOUND YR PRODUKT OF 6.28 AN RADIUS BTW this will return radius * 6.28
  
  GTFO BTW this would simply exit from the function
IF U SAY SO

KTHXBYE

Calling functions

To call a function, use I IZ statement followed by the name of your function and the optional list of arguments YR ARGUMENT1 AN YR ARGUMENT 2 .... Close the statement with the MKAY keyword:

HAI 1.2

HOW IZ I CALCULATE_CIRCLE_PERIMETER_FOR YR RADIUS
  I HAS A result
  result R PRODUKT OF 6.28 AN RADIUS
  FOUND YR result
IF U SAY SO
  
VISIBLE I IZ CALCULATE_CIRCLE_PERIMETER_FOR YR 10 MKAY

KTHXBYE

So, in this instance we are calculating the perimeter of a circle using the given radius and then outputting it to the screen. Of course, we can further enhance this program:

HAI 1.2
  HOW IZ I CALCULATE_CIRCLE_PERIMETER YR RADIUS
    I HAS A RESULT
  
  BOTH SAEM RADIUS AN 0, O RLY?
      YA RLY, GTFO
      NO WAI
      RESULT R PRODUKT OF 6.28 AN RADIUS
        FOUND YR RESULT
    OIC
  IF U SAY SO
  
  I HAS A RADIUS
  I HAS A PERIMETER
  VISIBLE "GIMME YER RADIUS:"
  GIMMEH RADIUS
  
  RADIUS IS NOW A NUMBR
  
  PERIMETER R I IZ CALCULATE_CIRCLE_PERIMETER YR RADIUS MKAY
  PERIMETER IS NOW A YARN
  
  VISIBLE "YER PERIMETER IZ " PERIMETER
KTHXBYE

Here we are asking the user to enter the radius value and then convert it to NUMBR. Next, we call the function and check whether the radius is equal to 0. If yes — exit from the function immediately with GTFO. In this case, the result value will have a NOOB type which cannot be implicitly converted to YARN (string) when printing the result on the screen. To fix this issue, we explicitly convert PERIMETER to YARN. If the radius is not zero, we calculate perimeter as before and return the result.

Recursion

Lastly, let’s see how to write recursive functions in LOLCODE. As an example, we are going to calculate the factorial of a given number. Remember that the factorial for n is calculated as n * (n - 1) * (n - 2) * ... * 3 * 2 * 1. Also, the factorial of 0! is 1, while the factorial for negative numbers is undefined (but for simplicity we’ll assume it also equals to 1).

HAI 1.2
  HOW IZ I CALCULATE_FACTORIAL YR FACT_NUMBER AN YR RESULT
    DIFFRINT FACT_NUMBER AN BIGGR OF FACT_NUMBER AN 2, O RLY?
      YA RLY, FOUND YR RESULT
    OIC
  
    I HAS A NEW_FACT_NUMBER
    I HAS A NEW_RESULT
  
    NEW_FACT_NUMBER R DIFF OF FACT_NUMBER AN 1
    NEW_RESULT R PRODUKT OF RESULT AN FACT_NUMBER
  
    FOUND YR I IZ CALCULATE_FACTORIAL YR NEW_FACT_NUMBER AN YR NEW_RESULT MKAY
  IF U SAY SO
  
  I HAS A FACT_NUMBER
  
  VISIBLE "GIMME YER NUMBER:"
  GIMMEH FACT_NUMBER
  
  FACT_NUMBER IS NOW A NUMBR
   
  VISIBLE "YER RESULT " I IZ CALCULATE_FACTORIAL YR FACT_NUMBER AN YR 1 MKAY
KTHXBYE

So, how does this program work?

  • We have a function, CALCULATE_FACTORIAL which accepts a number (our n) and the result.
  • Then, we check whether n is less than 2. If that’s true, we simply return the current result and recursion stops.
  • If that’s false, we decrement n by 1 and calculate a new result by multiplying the old result and the old n.
  • Next, we call the same function again with a new n and a new result.
  • Outside the function we ask the user to enter a number and convert it to NUMBR type.
  • Finally, we call our recursive function and print its result to the screen.

Great job!

Conclusion

So, in this post we had some fun and discussed LOLCODE — an esoteric language for cat lovers. Of course, this language is not ready for production use, but it could be interesting to rewrite some your existing programs with LOLCODE as an experiment. That’s it for today, folks! Wishing you a Happy Christmas, and until the next time!

Related posts

Sign up to our newsletter

Get the latest articles on all things data delivered straight to your inbox.

Read also
Localization made easy. Why wait?
The preferred localization tool of 2000+ companies