{set $name = value} evaluates the value and assigns it to a global variable,
which every tag after it can read as {$name}. Several assignments go in one tag,
separated by commas. The tag prints nothing.
The assignment sticks: a {set} inside a loop, an {if} or any other
level outlives it, so a loop can add up a total that is still there after the loop. That is
the difference with a $name = value written on another tag -
{orders $n = 5} - which is that level's own and is unwound when the level
closes, and with %name = value, which is set again for every occurrence.
The values of one {set} are evaluated before any of them is assigned: in
{set $a = 1, $b = $a + 1} the $a on the right is the value from before
the tag (an error when there was none). Write two {set} tags when one value builds
on another.
Under the strict syntax check a {set} written as a pair, or one whose words
hold no $name = value assignment (a missing $, a missing value), is an
error. To count, {increment} and
{decrement} are shorter; to keep a list or a piece of template,
{data} and {content}.