Homespring Tutorial: "A step-by-step guide into insanity"
Jeff Binder | Homespring Home


If you are new to programming, you should probably start somewhere else. This is not intended to be a usable language, and it may permanately sour you on programming. It is in no way representative of what programming is like. This tutorial assumes you know some real language already. You have been warned. Your milage may vary. May cause birth defects.

Before you can start writing Homespring code, you need to understand its lexical structure, that is, the meanings of various characters. It's pretty simple; programs are divided into tokens seperated by single spaces or newlines. So the program

Hello, world

contains two tokens, 'Hello,' and 'world'. If you double the space inbetween the words there, you will create a blank token inbetween 'Hello' and 'World'. These blank tokens have a special meaning that we'll get to later. So remember that tokens are seperated by a single space. Two spaces is not the same as one space.

Tokens can also be seperated by newlines, so this


is equivalent to the above. Now what if you want a space in a token? You have to escape it using a period ('.'). So this

Hello,. world

is interpreted as one token, 'Hello, world'. If you happen to want an actual period in a token, you need to escape it too. But as it so happens, periods are escaped with spaces. So,

Hello,. world .

means 'Hello, world.'. Finally, if you want to put a newline in a token, use a period that is not followed or preceded by a space. So to put a newline at the end of that Hello World token, do this:

Hello,. world ..

But, of course, if you put another token after that, the period is instead used to escape the space, making them one token. To get around this, you need to put all tokens that end in newlines at the end of a line, and all tokens that begin in newlines at the beginning. And if you want a token that's just a newline, use a period on a line by itself.

So what happens when you have a program containing space-dot-space or dot-space-dot? Who knows?

Program Structure

All HS programs take the form of trees. The way the tokens are put together into a tree is kind of unusual. Let's look at an example:

a b c

This program is parsed into this tree:


As you see, each token is a child of the preceding token. To change this, you have to use the special blank tokens, which tell the parser to move up a level. So:

a b  c



If the parser can't move down any more, the blank token is just treated like a normal token. So yes, every possible string of characters is a valid Homespring program! Also, it should be noted that the null program (that is, a completely blank program) is special. When this program is run, the interpreter prints the message 'In Homespring, the null program is not a quine.' and exits.

The program we'll be looking at in the next section:

bear hatchery Hello,. World ..

Is interpreted as:

Hello, world.\n
    /        \
bear         powers

What This Does

The basic idea here is that of salmon. Yes, salmon. The program is a tree or rivers that flow out into the ocean. In our example program, the 'bear' is at the point where the river flows out into the ocean. The ocean represents the input and output streams.

Now back to the salmon. Whenever a line of input is read, it is encapsulated in a salmon. This salmon swims upstream looking for its home, the place where it hatched. Once it reaches its home, it spawns. The salmon's value (the line of input that it represents) determines which node is its home. So if the salmon's value is 'Hello, World.\n', its home is that node.

Salmon that can't find their home just go as far as they can to the top side of the tree, until they can go no further. They spawn there.

When a salmon spawns, it creates a new salmon. This salmon has the value of the spring where it was hatched, regardless of its parent's value. Also, the new salmon is young. This can affect a number of things, as we shall see. If the salmon that spawns is young, it becomes mature (not young). Anyway, both salmon now swim downstream, until they reach the ocean. Once they do, their values are output.

The salmon have a specified order in the list, and they are output in that order. New salmon are inserted at the beginning of the list. Oddly enough, the order of the list is reversed every time they enter a new node.

So what does our example program do?

The first node is a 'bear'. We'll get to that later, because the program really starts with the 'powers'.

'powers' generates electricity. Everything downstream of the 'powers' node gets power, unless the electricity is blocked somehow.

'hatchery' is the main thing here. It keeps creating new salmon whenever it's powered. These salmon are mature, have the value 'homeless' and immediately swim upstream like an input salmon.

Since there is no node called 'homeless', the salmon just swims up the top branch, and stops at 'Hello, world.\n' Here it spawns. So now there are two salmon there, a mature one called 'homeless' and a young one called 'Hello, world.\n'.

The 'Hello, world!\n' node is a spring. Any node that isn't a keyword is a spring. Springs generate water, which flows downstream. Water doesn't enter into this program (it's assumed that there's always enough for salmon to swim), but it needed to be mentioned somewhere.

These two salmon now swim downstream. Before long they reach 'bear'. 'bear' eats mature salmon. Young salmon are too small for bears. So now only the 'Hello, world.\n' salmon is left. It exits and its value is displayed.

Of course, all this while, the hatchery is still doing its thing, so the program prints 'Hello, world.\n' ad infinitum. We'll fix that next.

Making a Program that Actually Ends

Here it is:

universe bear hatchery Hello,. world!.
 powers   marshy marshy snowmelt


                      Hello, world!
             /        \               
         bear          powers         /
        /    \                  marshy
universe      marshy _________ /

This is the same as the other program, but with a few things added. The 'snowmelt' node creates snowmelt, which flows downstream like water. It destroys certain things.

The 'marshy' nodes slow down snowmelt, so it takes two ticks for it to pass through them.

The 'universe' is the entire cosmos of the program. It can be smashed up by snowmelt. So when snowmelt hits it, the program ends. It is timed so it ends just after the first 'Hello, world!\n' message makes it out.

It should be noted that snowmelt is updated first, then water, then electricity, then salmon, then special things like bear.


This program works, but it doesn't really have complete sentences. It's better written like this:

Universe of bear hatchery says Hello. World!.
 It   powers     the marshy things;
the power of the snowmelt overrides.

This program is functionally equivalent, but it looks like a strange poem. That is considered a Good Thing is HS terms.

One last note: some keywords have spaces in them. Remember to escape them with periods.


Here are all of the keywords:

Electric Generators
This was described above.

hydro power
Generates electricity only when supplied with water. This can be destroyed by snowmelt.

power invert
Blocks electricity; generates electricity when not powered. This can be destroyed by snowmelt.

This was described above.

Similar to marshy, but it affects mature salmon.

Similar to shallows, but for young salmon.

This was described above.

young bear
Like a bear, but only kills every other mature fish.

Like a bear, but kills young fish.

upstream killing device
Kills salmon in the node up the bottom branch when powered.

Blocks mature salmon.

Blocks young salmon.

Blocks electricity.

force field
Blocks everything when powered. Things can enter it, but they can't pass through it.

Blocks everything if it is destroyed by snowmelt.

Blocks fish moving upstream. They can enter it, but they can't pass through it. As such they will spawn at the waterfall.

Blocks water and snowmelt when powered.

Fish can only enter this node when it is powered.

Fish can not enter this node when it is powered.

Downstream salmon cannot enter this node when it is powered.

inverse lock
Downstream salmon cannot enter this node unless it is powered.

Only one salmon can enter at a time.

Sense and Switch
Blocks electricity when at least one mature salmon is present.

Only allows electricity through when at least one mature salmon is present.

upstream sense
downstream sense
Only work for fish going in the specified direction.

range sense
range switch
Detect fish in the node or anywhere upstream.

young sense
young switch
young range sense
young range switch
Work for young salmon instread of mature salmon.

Salmon Age
youth fountain
Makes salmon young.

Makes salmon mature.

reverse up
Send fish coming downstream from the lower branch up the upper branch.

reverse down
Send fish coming downstream from the upper branch up the lower branch.

force up
Like reverse up, except upstream salmon can't go up the upper branch.

force down
Like reverse down, except upstream salmon can't go up the lower branch.

This was described above.

This was described above.

append down
Appends the values of fish coming down from the bottom branch in turn onto the end of the values of salmon coming down from the top branch. The salmon from the bottom are destroyed in the process.

append up
Similar to append down but the top and bottom branches are reversed.

Immediately creates a young copy of all salmon that pass through and sends them downstream. It doesn't affect the salmon that pass through.

This was described above.

When powered, changed the value of all salmon to ''. Can be destroyed by snowmelt.

When supplied with electricity, causes all fish upstream to spawn immediately. Be careful with this: it can lead to exponential growth!

Splits each salmon into a salmon of each character of its value. They have the same maturity and direction as the salmon.

Copyright (C) 2003 Jeff Binder

Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.