CAPSULES: SATELLITE FUNCTIONS
A capsule is satellite’s word for a function: a piece of work with a name, which you write once and call as often as you like. You have already met one. satellite.main is a capsule, and every program starts inside it. This post shows how to write your own.
Writing a capsule
A capsule is declared at the top level of a file, beside satellite.main. It has a name, its parameters in brackets, and its body between { and }. Each parameter is written the way every declaration in satellite is written: the type first, then the name. Commas go between them, and a capsule that takes nothing has empty brackets.
When a capsule gives an answer back, satellite.return(value) inside its body hands the answer back and ends the capsule on the spot. Nothing after the brackets says what kind of answer it is: a capsule answers whatever it hands back.
(satellite)
satellite.capsule area(satellite.variable.number width, satellite.variable.number height)
{
satellite.return(width * height)
}
satellite.capsule satellite.main()
{
satellite.variable.number floor = area(4, 5)
satellite.console.display(floor)
satellite.console.display(area(2, 3) + area(1, 1))
describe("kitchen", area(3, 3))
satellite.return(satellite)
}
satellite.capsule describe(satellite.variable.string room, satellite.variable.number size)
{
satellite.console.display("the " + room + " is " + size.string + " square metres")
}20
7
the kitchen is 9 square metresA few things to notice:
- You call a capsule by its name with its arguments in brackets. A capsule that answers can be called inside any line, as
area(4, 5)is, and one that answers nothing is called on a line of its own, asdescribe(...)is. areaanddescribeare bare names, because they are yours.satellite.mainandsatellite.returnstart withsatellite, because they belong to the language.describeis written aftersatellite.main, and that is fine: the order capsules are declared in does not matter.describehas nosatellite.return. A capsule that answers nothing may simply reach its closing}.
What a capsule can see
A capsule runs in a space of its own. It cannot see the variables of the capsule that called it, and there are no global variables in satellite either, so what you hand a capsule is all it has. That keeps every capsule honest: to know what it works with, you only have to read its brackets.
(satellite)
satellite.capsule show_score()
{
satellite.console.display(score)
}
satellite.capsule satellite.main()
{
satellite.variable.number score = 10
show_score()
satellite.return(satellite)
}--------------------------------------------------------------------------------
SATELLITE CRITICAL ERROR REPORT
--------------------------------------------------------------------------------
S201: NAME_NOT_DECLARED
satl(check): in show_score, score has no satellite.variable line declaring it
directory: scope.satl:5
syntax: satellite.console.display(score)
/\
this name was used and no satellite.variable line ever declared it. A name has
to be given a type before it can hold anything.
machine code 25 name_not_declared -- satl exits with this.
--------------------------------------------------------------------------------The fix is to hand the score over: declare show_score(satellite.variable.number score) and call show_score(score).
satl measures every call, too. A call with the wrong number of arguments is refused before the program starts (S110), and an argument of the wrong type is refused when the call is reached: calling area("four", 5) stops with “area’s width was declared satellite.variable.number, and it holds a string”.
A capsule that calls itself
A capsule may call itself. This is called recursion, and satellite treats it in two ways, depending on where the call stands.
When the call to itself is the very last thing the capsule does, it is a loop. satl does not stack up a new level for each call; it simply goes round again. Such a capsule can go as deep as you like: here the second capsule goes a hundred thousand levels down.
(satellite)
satellite.capsule count_down(satellite.variable.number n)
{
satellite.console.display(n)
satellite.statement.if (n > 0)
{
count_down(n - 1)
}
}
satellite.capsule dive(satellite.variable.number depth)
{
satellite.statement.if (depth == 0)
{
satellite.console.display("reached the bottom")
}
satellite.statement.else
{
dive(depth - 1)
}
}
satellite.capsule satellite.main()
{
count_down(3)
dive(100000)
satellite.return(satellite)
}3
2
1
0
reached the bottom“The last thing” can sit inside an if or an else, as both of these do, as long as nothing in the capsule runs after it.
When the call to itself has work after it, it is an ordinary call. satl keeps each level waiting until the one below it finishes, and then carries on with the lines after the call, in order:
(satellite)
satellite.capsule climb(satellite.variable.number n)
{
satellite.statement.if (n > 0)
{
climb(n - 1)
}
satellite.console.display(n)
}
satellite.capsule satellite.main()
{
climb(3)
satellite.return(satellite)
}0
1
2
3Each waiting level takes memory, so this shape uses more than the last-line shape does — a few kilobytes a level — but it has no depth limit of its own: when a program goes deep enough to fill the room it started with, satl moves on to fresh room and keeps going. A million levels deep is a few gigabytes while it is that deep, and all of it is given back on the way up. The only limit is your computer’s memory. The last-line shape needs none of that, so a capsule that has to go very deep is still best written with its call to itself last.
A call written inside
satellite.return(...), such assatellite.return(total(n - 1)), is an ordinary call too, because handing the answer back is work left after it.
Where next
The FULL REFERENCE lists every rule for capsules. The loops that capsules usually hold are in IF, WHILE AND FOR, and capsules shared between files and grouped into namespaces are in INCLUDING FILES AND NAMESPACES.

1 Response
[…] the language has is in the FULL REFERENCE. To write capsules of your own, read CAPSULES: SATELLITE FUNCTIONS. For more about printing, read DISPLAYING TEXT, and for everything satl can do from the command […]