Getting Started with Rant

This guide will walk you through the basics of the Rant language and creating some simple programs.

First, follow the instructions on the Installation guide to install Rant as a standalone application. Make sure it installs smoothly and the rant command works, since we'll be using that to run programs.

Rant is all about printing

At its core, Rant is a hybrid of a markup language and an imperative programming language. Not only can you print to the output, but you can also call functions, define variables, modify stored variables, and other imperative stuff.

This has a few major implications for program structure. The most obvious one is that most plain text will come out the same way it went in.

Hello world!
# Prints "Hello world!"

This also makes it very intuitive to add branching options to some text. To do this, we use a block.

A block is simply an array of smaller Rant programs. Blocks can contain as many elements as you want, and the elements can be any valid Rant code (even nothing at all).

{Hello|Hi|Hey} world!

In the above snippet, we have a block with three elements. Blocks are denoted by a pair of curly braces with pipe characters separating the elements.

Try writing the above example in the Rant REPL and running it a few times. Right away, you'll probably notice that the output will be one of three strings:

  • "Hello world!"
  • "Hi world!"
  • "Hey world!"
By default, Rant chooses a random block element to run; however, this can be customized (more about this later).

Blocks are Rant's most powerful feature. You will see later in this guide how they can do much more than simple branching.

Functions

At this point you are probably bored of printing text with some random branches. Let's try calling some functions to add more variation to our output.

Rant has a modestly-sized standard library of functions that are tailored to procedural generation use cases. Let's check out some of Rant's generator functions, which are used to generate random numbers, strings, and more.

Function calls are done inside of square brackets, like [this]. The word inside the brackets is the name of the function to call. Let's look at a very basic function that doesn't need any arguments:

[dig]

Paste that into the Rant CLI and run it a few times. It should print a single, random decimal digit, e.g. 4. 4

Let's make it do something different. Change the function call to look like this and try running it again:

[dig: 16]

When you run this, it will print a much bigger string of digits-- 16 digits, to be exact.

1153687747958403

What you just did was pass an argument, a digit count, to the [dig] function to change how many digits it generates.

But what about multiple arguments? Let's try something slightly different. Let's call the [num] function, which generates a random integer, and pass in the minimum and maximum values our random number should be.

# Generate an integer between 1 and 100 (inclusive)
[num: 1; 100]

Running this, you should get an output of some number between 1 and 100:

41

When calling a function with arguments, the same pattern is always followed: a colon comes after the function name, and then an argument list delimited with semicolons.

The great and powerful block

As mentioned earlier, blocks have a few different uses in Rant. In this section we will explore one such use: the repeater.

When Rant runs a block, it looks at a set of registers called block attributes. Block attributes control various aspects of block behavior, such as repetition count, separators, selection behavior, and other fine details. The user can set these attributes to change what the next block does when it resolves.

A repeater is nothing but a block that can run multiple times in a row. To do this, we set the "repetitions" attribute using the [rep] function.

Try running this code:

[rep:10]{Heads\n|Tails\n}

The output should look similar to this:

Tails
Tails
Heads
Tails
Heads
Heads
Heads
Tails
Tails
Heads

What's happening here is that the [rep:10] call affects the number of times the block after it will run. Each times the block runs, Rant treats it like a completely new block, selecting a random branch each time!

You may have noticed the little \n after each element. This is an escape sequence, which are used to print special characters. The \n escape sequence prints a newline.

It's probably not too bad to add this separator at the end of "Heads" and "Tails", but if we add more options, it's a bit messy to repeat the separator on each element. It's also prone to errors. Luckily, Rant has a separator attribute just for this!

To add a separator to a repeater, call the [sep] function and pass in your separator value as an argument. Let's modify our coin-flipping program from before to take advantage of this:

[rep:10][sep:\n]{Heads|Tails}

Running this again, we can see that it produces almost the exact same output format:

Tails
Tails
Heads
Heads
Tails
Tails
Tails
Tails
Heads
Heads

There is one important difference to note about using [sep] versus an explicit separator on each element: the last element will not have any separator after it! This makes [sep] super useful for cases where you only want a separator between two elements.

Selectors

There is one more important block attribute we haven't covered yet: the selector. Selectors tell Rant how to choose which branch of a block to run. There are many use cases where different selection strategies are desirable, and selectors make it easy!

TODO