This page acts as something of a glossary for several concepts that recur throughout the Pancode language. It's not really intended to be read linearly, as the relevant sections are linked from the documentation when they're mentioned.
Many commands which are designed to be binary may be extended
with a numerical modifier. In
particular, if given a numerical modifier of N, these commands
will take N arguments and fold the argument list using the
binary command. For instance, +
is a command which
adds two numbers, while +⑧
is a command which adds
eight numbers.
If a command with binary extension does not specify its
associativity, you may assume it associates to the left, so a b c +③
will
do (a + b) + c
not a + (b + c)
. This
is irrelevant for associative commands but can come into play
for others such as -
.
If a command subject to binary extension is given the numerical
modifier of 0 or 1, special behavior often triggers. This
behavior is specific to the given command but follows a general
theme. If given numerical modifier zero, a command will
generally produce its identity or neutral value, e.g. zero for
addition or one for multiplication. If there's no sensible
identity, a numerical modifier of zero results in an error. If
given a numerical modifier one, "negative" commands like -
and
÷
will return the inverse of their sole argument
(respectively, the additive and multiplicative inverse).
"Positive" commands like +
and ×
will
return their argument untouched.
If both scalar extension and binary extension apply to a command, binary extension applies first, and scalar extension applies to the resulting binary command.
Many commands take optional numerical modifier. These are
distinct from standard stack-based arguments in that they are
provided as constants to the command itself. Numerical modifiers
can be any value from 0 to 20 and are given by placing the
"Circled Digit" characters (⓪ to ⑳) after the command itself.
For instance, to supply a numerical argument of 4 to +
,
you would write +④
.
These circled characters can be typed using \(0)
, \(1)
,
etc. Numerical modifiers are always optional and will take
reasonable defaults if not provided. If too many numerical
modifiers are provided, the excess ones will be ignored
silently.
In addition to a numerical modifier, some commands may take a
prime modifier. A prime modifier is supplied by placing ′
after the command. Prime modifiers and numerical modifiers may
be specified in either order. If supplied, the prime modifier
will generally perform some modified but similar version of the
command. For instance, ⍋
sorts
a list using the default ordering, but ⍋′
takes a
custom sorting function and sorts the list according to that
function.
You may supply the prime modifier any number of times to a command. Generally speaking, commands may offer different variants depending on how many primes are provided, but as of right now there are no commands which accept more than one prime modifier.
Some commands provide scalar extension behavior. Effectively, this means that if given a list argument, the command will automatically apply to each element of the list.
The simplest case is scalar extension applied to a unary
command, such as the negation command _
. By default, _
takes
a single number argument and returns its additive inverse.
3 _ « Produces -3 »
However, if applied to a list, it will happily negate every element of that list, recursively applying to nested lists as well.
{1 {2} {{3} 4}} _ « Produces {-1 {-2} {{-3} -4}} »
For binary commands, scalar extension is slightly more complex. If given two non-lists, the command simply runs normally on the two arguments. If given one list and one non-list, it runs on each element of the list, keeping the other argument constant. If given two lists, the lists must be the same length, and it zips the lists together, applying the command to each corresponding pair. Like in the unary case, this extension will happily recurse arbitrarily deeply into nested lists.
Here are some examples, using the binary command +
,
which applies the scalar extension rules.
1 2 + « Produces 3 »
{1 2 3} 10 + « Produces {11 12 13} »
{1 2 3} {10 20 30} + « Produces {11 22 33} »
{{1 2} {3 4}} {10 20} + « Produces {{11 12} {23 24}} »
For commands where both scalar extension and either binary or transitive extension would apply, the latter takes precedent first, converting the command into a binary one, and then scalar extension acts on the resulting binary command.
Transitive extension is similar to binary extension,
in that it takes a traditionally binary command and uses its
numerical modifier to extend
it to an n-ary command. Transitive extension mainly applies to
comparison-oriented commands, such as <
and >
.
Transitive extension applies the binary command to each pair of
adjacent arguments and then returns true if all of the results
are true, or false otherwise. For instance,
1 2 3 4 <④
This code will check whether 1 < 2
, then check
whether 2 < 3
, then whether 3 < 4
, and
return true since all of those are true.
Unless otherwise specified, a numerical modifier of zero to a command which supports transitive extension will simply return true, while a numerical modifier of one will produce an error. In a case where both scalar extension and transitive extension apply, transitive extension applies first, and scalar extension applies to the resulting binary command.