BQN primitives

Primitives are the basic functions and modifiers built into the language, written with individual glyphs (more about the concept here). The role of a primitive when written always matches its type (but you can use its value in other roles by assigning it, or other methods).

Primitives have no side effects other than errors, and can't perform infinite computations, except when a primitive modifier calls an operand function that does one of these things (this can only happen when arguments are passed, as primitive modifiers are always deferred). Side effects here include both writing state such as variables or printed output, and reading any outside state, so that a function without them always returns the same result if passed the same arguments. Since trains and list notation have the same nice properties, tacit code written entirely with primitives, trains, and lists always describes finite, self-contained computations.

Recursion is the primary way to perform potentially infinite computations in BQN, and it can be packaged into control structures like While for ease of use. A given BQN implementation might also provide system values for "impure" tasks like file access or other I/O.

Functions

Functions that have significant differences from APL equivalents or don't appear in APL are marked with an asterisk.

Glyph Monadic Dyadic
+ Conjugate Add
- Negate Subtract
× Sign Multiply
÷ Reciprocal Divide
Exponential Power
Square Root Root
Floor Minimum
Ceiling Maximum
Sort Up And*
Sort Down Or*
¬ Not* Span*
| Absolute Value Modulus
Less Than or Equal to
< Enclose Less Than
> Merge* Greater Than
Greater Than or Equal to
= Rank* Equals
Length Not Equals
Depth* Match
Shape Not Match
Identity Left
Identity Right
Deshape Reshape*
Join* Join to
Solo* Couple*
Enlist* Pair*
Prefixes* Take
Suffixes* Drop
Range Windows*
» Nudge* Shift Before*
« Nudge Back* Shift After*
Reverse Rotate
Transpose* Reorder axes*
/ Indices Replicate
Grade Up Bins Up
Grade Down Bins Down
First Cell* Select*
First Pick*
Classify* Index of
Occurrence Count* Progressive Index of*
Mark Firsts Member of
Deduplicate Find
Group Indices* Group*
! Assert* Assert with Message*

Modifiers

Atop 𝔽𝔾 𝕩 𝔽 𝔾 𝕩 𝕨 𝔽𝔾 𝕩 𝔽 𝔾 𝕨 𝕩 Over 𝔽𝔾 𝕩 𝔽 𝔾 𝕩 𝕨 𝔽𝔾 𝕩 𝔽 𝔾 𝔾 𝕨 𝕩 Constant 𝕗˙ 𝕩 𝕗 𝕩 𝕨 𝕗˙ 𝕩 𝕗 𝕨 𝕩 Before 𝔽𝔾 𝕩 𝔾 𝔽 𝕩 𝕨 𝔽𝔾 𝕩 𝔾 𝔽 𝕨 𝕩 After 𝔽𝔾 𝕩 𝔽 𝔾 𝕩 𝕨 𝔽𝔾 𝕩 𝔽 𝔾 𝕨 𝕩 Self/Swap 𝔽˜ 𝕩 𝔽 𝕩 𝕨 𝔽˜ 𝕩 𝔽 𝕨 𝕩

Combinators only control the application of functions. Because a non-function operand applies as a constant function, some combinators have extra meanings when passed a constant. For example, 0˜ is identical to 0˙—a constant function that always returns 0—and 0< is the function that tests whether its right argument is greater than 0.

Glyph Name(s) Definition Description
˙ Constant {𝕩𝕗} Return a function that returns the operand
˜ Self/Swap {𝕩𝔽𝕨𝕩} Duplicate one argument or exchange two
Atop {𝔽𝕨𝔾𝕩} Apply 𝔾 to both arguments and 𝔽 to the result
Over {(𝔾𝕨)𝔽𝔾𝕩} Apply 𝔾 to each argument and 𝔽 to the results
Before/Bind {(𝔽𝕨𝕩)𝔾𝕩} 𝔾's left argument comes from 𝔽
After/Bind {(𝕨𝕩)𝔽𝔾𝕩} 𝔽's right argument comes from 𝔾
Under {𝔾𝔽𝔾} OR {(𝔾𝕩)𝕨𝔽𝔾𝕩𝕩} Apply 𝔽 over 𝔾, then undo 𝔾
Valences {𝔽𝕩;𝕨𝔾𝕩} Apply 𝔽 if there's one argument but 𝔾 if there are two
Choose {f(𝕨𝔽𝕩)𝕘 𝕨F𝕩} Select one of the functions in list 𝕘 based on 𝔽

Choose isn't really a combinator since it calls the function , and Under is not a true combinator since it has an "undo" step at the end. This step might be implemented using the left operand's inverse (computational Under) or its structural properties (structural Under).

Other modifiers control array traversal and iteration. In three cases a simpler 1-modifier is paired with a generalized 2-modifier: in each case the 1-modifier happens to be the same as the 2-modifier with a right operand of ¯1.

1-Modifier Name 2-Modifier Name
˘ Cells Rank
¨ Each Depth
Table
Undo Repeat
´ Fold
˝ Insert
` Scan