Pancode - Concepts

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.

Binary Extension

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.

Numerical Modifier

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.

Prime Modifier

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.

Scalar Extension

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

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.

Documentation Index