# BasedPL

> BPL, the Based-array Programming Language, is an array language derived from APL, with ideas from J and BQN. Assume Dyalog APL with `⎕ML≥2`, where `↑` is first and take and `⊃` is mix and pick, except where an entry below says otherwise. Most APL idioms don't apply to BPL. Write BPL, not APL.

Each entry below names a difference from Dyalog APL, gives a short example, and links the page that defines it. The entries are not the reference. Every time you rely on anything an entry mentions, read the page it links first. Links are relative to https://answerdotai.github.io/basedpl/. In a BPL session, `]help` followed by a glyph or system function shows its page, as in `]help ⍳`.

## Terms

- [Terms](terms.html.md): ensure you've read the full Terms page before reading any reference page. It defines many terms, including these:
  - atom: a value that isn't an array: a number, character, function or operator. `5` is an atom.
  - scalar: an array of rank 0 holding one value. `⊂5` is a scalar, while `5` is not.
  - run: glyphs, names, literals and groups with no spaces between them. A group is code in brackets, parentheses or braces, and may contain spaces: `+/÷≢` is one run, and so is `x.[1 2]`.
  - key: a string that labels one position along an axis. It's unrelated to the Key operator, `⌸`.

## Language

- [Syntax](syntax.html.md): spaces divide a statement into runs, each read as one parenthesised group: `a+b × c+d` is `(a+b)(×)(c+d)`. Digits in a name need `_`, as in `x_1`. `x1` is `x` applied to `1`.
- [Evaluation](evaluation.html.md): a run that ends in a function is a train. `+/÷≢ x` is the mean of `x`, while `+/÷≢x` reads as `+/÷(≢x)`.
- [Agreement](evaluation.html.md#agreement-and-pervasion): pervasive functions, Each and Rank align leading axes: `[1 2 3⋄4 5 6]+10 20` is `[11 12 13⋄24 25 26]`. An axis of length 1 expands.
- [Maps](evaluation.html.md#functions-and-effects): Each, Rank, stencils and outer products call a dfn once on all their cells where they can: `{⍵×⍵+1}¨v` costs about what `v×v+1` costs. A predicate on a cell's value runs each body once, on the cells that take it. Output or a nested result makes them call the dfn once for each cell. A fold or scan by a dfn along each row of a matrix calls it once for each column, on every row at once. `f.g` calls a dfn `g` once, on all its pairings.
- [Arrays](arrays.html.md): numbers, characters and functions are atoms, distinct from scalars, as in BQN. `⊂` always adds a layer: `⊂3 ≡ 3` is `$f`.
- [Brackets](glyphs/brackets.html.md): `[a b]` is a vector, even `[a]`. Inside brackets, spaces separate items. `;` separates items, each read as if parenthesised: `[1 2;3 4]` is `[(1 2) (3 4)]`, two items. `⋄` separates rows: `[1 2⋄3 4]` is a matrix. `"k":v` items make a record: `["a":1 "b":2]`.
- [Characters and strings](strings.html.md): `"abc"` is a character vector. `'a'` is one character atom. A single-quoted string such as `'abc'` is an error.
- [Indexing](indexing.html.md): `Y[I]` isn't BPL. `I⌷A` takes a cross product, while `A.[I J]` pairs its index arrays as NumPy does: with `i←⍳3`, `m.[i i]` is the diagonal. Positions count from 0. Negative positions count from the end.
- [Numbers](numbers.html.md): bare numbers behave as in Dyalog. BPL adds exact integers, as in `3ₓ`, and exact rationals, as in `1r3`, and arithmetic on exact numbers stays exact.
- [Superscripts and subscripts](scripts.html.md): `x²` is `x*2`, `f⁻¹` is the inverse of `f`, `v₁` is `1⌷v`, and `nₓ` is `⌊n`. Between names, `xⱼy` is `x+y×0ⱼ1`, `xₑy` is `x×10*y` and `xᵣy` is `xₓ÷yₓ`.
- [Keyed arrays](keyed.html.md): axes can have names and keys. `T.a` reads field `a` of a record, and `⊢.a` is `{⍵.a}`. Arithmetic pairs axes by name: with `i←⍳["i":3]` and `j←⍳["j":3]`, `i+j` is a 3×3 table.
- [Dfns](dfns.html.md): BPL has only dfns, with no tradfns and no control structures such as `:If`. A dfn returns its last statement. A predicate picks a body, as in BQN: `{⍵<0?-⍵;⍵} ¯3` is `3`. An absent `⍺` drops out of expressions, as BQN's `𝕨` does. A dfn operator's operands are `⍶` and `⍹`, not `⍺⍺` and `⍵⍵`. `⍢` calls the operator recursively. An error guard names its kinds as text, as in `"DOMAIN"::`.
- [Assignment](assignment.html.md): `←` is local. Modified and selective updates change the nearest binding. `[a b]←Y` destructures the items of `Y` by position. A space before `←` makes the whole run the target: `[[0 2]]⌷v ←0`.
- [Modules and namespaces](modules.html.md): `•load "file.bpl"` runs a module and returns its public names as a record. Names that start with `_` are private.
- [Hanzi spellings](syntax.html.md#hanzi-spellings): hanzi are ordinary name characters. A leading `•prefs ["hanzi_aliases":$t]` enables aliases such as `加总` for `+/`. Non-alias Hanzi remain names; `_` quotes any next non-whitespace character into a name, as in `_加_总`.
- [Constants and `$` names](system/constants.html.md): `$t $f $n` are true, false and NaN. `$a` and `$d` hold the uppercase alphabet and the digits.
- [Style](style.html.md): read before writing any BPL.

## Glyphs

- [Glyph reference](glyphs.html.md): lists every glyph with its name. A glyph's page is `glyphs/<name>.html.md`. Read it before using the glyph.
- [Removed forms](glyphs.html.md#language-wide-differences-from-dyalog-apl): Dyalog's bracket indexing `Y[I]`, bracket axes `f[A]`, outer product `∘.f`, windowed reduce and laminate aren't in BPL.
- [`@` Under](glyphs/at.html.md): `f@g` applies `f` to what `g` selects and writes it back, as BQN's `⌾`, not Dyalog's `@`. `⌊@ 10× 1.25 2.78` is `1.2 2.7`. With positions or `[p]`, a left argument lines up with the right argument by position, or by key where both have keys: `10 20 30 +@[0 2] 1 2 3` is `11 2 33`.
- [`∘` atop](glyphs/jot.html.md): `⍺ f∘g ⍵` is `f ⍺ g ⍵`, as BQN's atop, where Dyalog's is `⍺ f g ⍵`. `10 -∘| ¯3` is `¯7`.
- [`⍤` rank](glyphs/jot-diaeresis.html.md): rank only: `+/⍤1 m` sums each row. A function right operand computes the ranks.
- [`⍠` axis](glyphs/quad-colon.html.md): applies a function along axes given by number or name. Both `+/⍠0 m` and `+/⍠"month" sales` sum along one axis, chosen by number in one and by name in the other.
- [`⌺` stencil](glyphs/quad-diamond.html.md): shorthand for Rank over centred windows: `f⌺3 v` is `f⍤¯1 [¯3]↕v`, and `life⌺[3 3] g` is `life⍤¯2 [¯3 ¯3]↕g`. `f` gets each window alone, with no `⍺`, as J's `;._3` calls its operand. A function right operand computes the window from the arguments.
- [`.` dot](glyphs/dot.html.md): after an array, `.name` reads a field and `.[I]` selects. Monadic `f.g` is J's determinant form: `-.×[1 2⋄3 4]` is `¯2`.
- [`⍣` power](glyphs/star-diaeresis.html.md): a list of counts keeps the history: `2×⍣(⍳5) 1` is `1 2 4 8 16`. `f⍣∞` finds a fixed point.
- [`/` reduce](glyphs/slash.html.md), [`⌿`](glyphs/slash-bar.html.md), [`\`](glyphs/backslash.html.md) and [`⍀`](glyphs/backslash-bar.html.md): only reduce and scan. A left argument is a seed, as in BQN: `2+/1 2 3` is `8`. Scans accumulate left to right.
- [`⍉` transpose](glyphs/circle-backslash.html.md): `A⍉Y` sends each axis of `Y` to the destination `A` gives it, as in BQN. `A⍉⁻¹Y` reorders axes as einops does: `["b" "patch":["i" "j"]]⍉⁻¹y`.
- [`⌷` index](glyphs/squad.html.md): selects along leading axes: `[[2 0]]⌷10 20 30` is `30 10`. `:` keeps one axis, `∞` the rest; `¯∞` inserts a length-one axis. Write `[: 1]`, not `[:1]`.
- [`⊃` pick](glyphs/right-shoe.html.md): pick follows a path, one level for each item: `[1 2]⊃v` is item 2 of item 1.
- [`⍳` iota](glyphs/iota.html.md): positions count from 0: `⍳3` is `0 1 2`. A negative argument counts down: `⍳¯3` is `2 1 0`.
- [`⍸` where](glyphs/iota-underbar.html.md): the dyad counts the items at or below each value, as BQN's `⍋`: `1 3 5⍸4 0 5` is `2 0 3`.
- [`=` classify](glyphs/equals.html.md) and [`≠` unique-mask](glyphs/not-equals.html.md): monadic `=` classifies, as in J. Monadic `≠` marks the first of each value: `≠3 1 3 2` is `$t $t $f $t`.
- [`<` sort-up](glyphs/less-than.html.md) and [`>` sort-down](glyphs/greater-than.html.md): the monads sort major cells: `<3 1 2` is `1 2 3`.
- [`≤` decrement](glyphs/less-than-or-equal.html.md) and [`≥` increment](glyphs/greater-than-or-equal.html.md): `≥3` is `4`.
- [`∨` real-imag](glyphs/vee.html.md) and [`∧` polar](glyphs/wedge.html.md): the monads are J's `+.` and `*.`.
- [`⊤`](glyphs/down-tack.html.md) and [`⊥`](glyphs/up-tack.html.md): digits go on the last axis, as in J. The monads encode and decode binary: `⊤5` is `1 0 1`.
- [`∊`](glyphs/epsilon.html.md), [`~`](glyphs/tilde.html.md), [`∪`](glyphs/down-shoe.html.md) and [`∩`](glyphs/up-shoe.html.md): compare major cells, as in BQN. Monadic `∩` gives duplicates: `∩1 2 2 3 3 3` is `2 3`.
- [`⊂`](glyphs/left-shoe.html.md) and [`⊆`](glyphs/left-shoe-underbar.html.md): partitions split the first axis. `⊂` always encloses, atoms included.
- [`⍷` groups](glyphs/epsilon-underbar.html.md): monadic `⍷` groups positions by value, as Dyalog's `{⊂⍵}⌸`.
- [`≡` match](glyphs/equal-underbar.html.md): depth is unsigned. An axis with no name or no keys matches any names or keys.
- [`+`](glyphs/plus.html.md) and [`-`](glyphs/minus.html.md): characters take offsets and differences, as in BQN: `'a'+1` is `'b'`.
- [`○` cis](glyphs/circle.html.md): the monad is cis. Pi-times is `π`.
- [`÷` divide](glyphs/obelus.html.md): exact numbers divide exactly, as in J: `1ₓ÷3ₓ` is `1ᵣ3`.
- [`⌹` matrix divide](glyphs/domino.html.md): gives the least-norm solution or pseudoinverse of a singular or wide matrix, where Dyalog raises an error.
- [`⍎` execute](glyphs/hydrant.html.md): `X⍎Y` evaluates `Y` with the keys of record `X` as names.
- [`⎕` quad](glyphs/quad.html.md): reading `⎕` gives a line of text. `⍎⎕` evaluates it.
- [`←` assign](glyphs/left-arrow.html.md): `a(f)←` with nothing after it sets `a` to `f a`.
- [`⍴` reshape](glyphs/rho.html.md): `⍬⍴Y` makes a rank-0 array.

## Glyphs that Dyalog lacks

- [`¿` roll](glyphs/inverted-question.html.md): roll and deal, Dyalog's `?`. `•prefs ["seed":42]` seeds it, in place of Dyalog's `⎕RL`.
- [`⊼` nand](glyphs/wedge-bar.html.md) and [`⊽` nor](glyphs/vee-bar.html.md): Dyalog's `⍲` and `⍱`. The monads square and double: `⊼3` is `9`.
- [`π` pi-times](glyphs/pi.html.md): `π1` is `3.141592654`.
- [`√` sqrt](glyphs/radical.html.md): square root and root, as BQN's `√`: `3√8` is `2`.
- [`⍭` primes](glyphs/stile-tilde.html.md): like J's `p:`, with different codes. `⍭⁻¹` counts primes.
- [`⨸` factors](glyphs/circle-divide.html.md): as J's `q:`: `⨸360ₓ` is `[2 2 2 3 3 5]ₓ`.
- [`⌻` polynomials](glyphs/quad-jot.html.md): roots and evaluation, as J's `p.`: `[1 2 3]⌻2` is `17`. Coefficients come from `⌻⁻¹`.
- [`↕` windows](glyphs/up-down-arrow.html.md): as BQN's `↕`: `+/3↕1 2 3 4 5` is `6 9 12`. Monadic `↕` is `2↕`. An options record pads by an edge mode: `["size":3 "edge":"wrap"]↕v`.
- [`#` replicate](glyphs/hash.html.md): along the first axis, as Dyalog's `⌿`: `1 0 2#"abc"` is `"acc"`. Monadic `#` gives run-length encoding. Dyadic `#⁻¹` expands.
- [`↦` range](glyphs/right-arrow-from-bar.html.md): `2↦5` counts from 2 to 5, giving `2 3 4 5`.
- [`:` keys](glyphs/colon.html.md): `K:Y` attaches keys to `Y`. `:Y` removes them.
- [`↣` before](glyphs/right-tail-arrow.html.md): as BQN's `⊸`. `a↣f` binds a left argument: `2↣×` doubles.
- [`↢` after](glyphs/left-tail-arrow.html.md): as BQN's `⟜`. `f↢a` binds a right argument: `*↢2` squares.
- [`⊗` outer product](glyphs/circle-times.html.md): as BQN's `⌜`, in place of `∘.f`: `1 2+⊗10 20` is `[11 21⋄12 22]`.
- [`⊘` valences](glyphs/circle-slash.html.md): `f⊘g` calls `f` with one argument and `g` with two, as BQN's `⊘`.
- [`⍚` agenda](glyphs/diamond-underbar.html.md): `selector⍚cases` calls the function that `selector` picks, as BQN's `◶`. A selector that isn't a unit picks a function for each cell: `(0≤)⍚[0 √] ¯4 9` is `0 3`.
- [`⇄` optimize](glyphs/right-left-arrows.html.md): `cost⇄ start` finds where `cost` is least, searching from `start`. A left argument holds options.
- [`∂` derivative](glyphs/partial.html.md): `f∂x` is the derivative, or Jacobian, of `f` at `x`: `{⍵*2}∂3` is `6`.
- [`ᵇ` bitwise](glyphs/superscript-b.html.md): applies a Boolean function to integer bits: `6∧ᵇ3` is `2ₓ`, and `~ᵇ6` is `¯7ₓ`.
- [`•` system](glyphs/bullet.html.md): starts a system name, as in `•json`, in place of Dyalog's `⎕NAME`.

## System functions

- [System functions](system-functions.html.md): names ignore case. Options are generally a keyed left argument. A format's function reads that format, as `•json` reads JSON. Its inverse writes it, as `•json⁻¹` does. A function's page is `system/<name>.html.md`, without the `•`. Read it before using the function.
- [Text](system-functions.html.md#text): `•c`, `•ucs`, `•normalize`, `•r`.
- [Data and files](system-functions.html.md#data-and-files): `•csv`, `•json`, `•literal`, `•vfi`, `•date`, `•nget`, `•nput`, `•fetch`, `•path`, `•metadata`, `•readdir`, `•copy`, `•rename`, `•remove`, `•mkdir`, `•deflate`, `•hash`, `•uuid`.
- [Display](system-functions.html.md#display): `•element`, `•xml`, `•svg`, `•mime`, `•plot`, `•image`, `•canvas`, `•prefs`.
- [Linear algebra](system-functions.html.md#linear-algebra): `•decompose`.
- [Random numbers and distributions](system-functions.html.md#random-numbers-and-distributions): `•rand`, `•distribution`.
- [Positions](system-functions.html.md#positions): `•index`, `•edge`.
- [Programs](system-functions.html.md#programs): `•load`, `•signal`, `•storage`, `•detach`, `•float`, `•time`, `•host`, `•delay`, and `•js` in the browser.
- [Introspection](system-functions.html.md#introspection): `•nc`, `•nl`, `•src`, `•ex`, `•explain`, `•memory`.

## Optional

- [Python](python.html.md): the `basedpl` package exposes all of BPL to Python: evaluation, arrays, and every function and operator by name.
- [BPL on the web](web.html.md): BPL running in a browser. The browser build adds `•js`.
