# Getting started


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Install

Requires Python 3.10 or later. On x86-64, it also requires a CPU with
AVX2 (x86-64-v3). Intel CPUs have had AVX2 since 2013 and AMD CPUs since
2015.

``` bash
pip install basedpl
```

This installs the `bpl` command and the `basedpl` Python package.

## First calculations

Run `bpl` to open the [REPL](repl.qmd). Type an expression and press
Enter. `⍝` starts a comment. The examples use comments to show each
result.

BPL evaluates right to left. Parentheses group, and so do spaces. BPL
evaluates each part between spaces first.

``` bpl
2×3+4                 ⍝ 14
(2×3)+4               ⍝ 10
2×3 + 4               ⍝ 10
```

    14

    10

    10

Numbers separated by spaces form a vector. Functions work on every item.

``` bpl
10+1 2 3              ⍝ 11 12 13
```

    11 12 13

`⍳` generates indices, `←` assigns a name, and `+/` sums.

``` bpl
v←⍳5 ⋄ v              ⍝ 0 1 2 3 4
+/⍳5                  ⍝ 10
```

    0 1 2 3 4

    10

To enter `⍳5`, type backtick, `iota`, then `5`. The digit accepts the
glyph and enters the argument. [Symbol entry](repl.qmd#typing-glyphs)
also supports abbreviations and Tab completion.

## Numbers and arrays

Bare numbers are approximate. Use `ₓ` for exact integers and `r` for
fractions.

``` bpl
1÷3                   ⍝ 0.3333333333333333
1ₓ÷3ₓ                 ⍝ 1ᵣ3
```

    0.3333333333

    1ᵣ3

`j` separates real and imaginary parts.

``` bpl
1j2×1j¯2              ⍝ 5
```

    5

`⍴` reshapes a vector; `+/` sums each row.

``` bpl
+/2 3⍴⍳6              ⍝ 3 12
```

    3 12

Indices start at 0, and negative indices count from the end. Comparisons
use a tolerance of `1E¯14`. For example, `0.3=0.1+0.2` is true. See the
[Language overview](overview.ipynb) and the [glyph index](glyphs.qmd).

## Nested arrays

A bracket list of vectors is a nested vector. Each (`¨`) applies its
operand to each item:

``` bpl
n←[[1 2] [3 4 5]]
+/¨n
```

    3 12

The same Each/reduction pattern works with division:

``` bpl
÷/¨n
```

    0.5 3.75

## Example algorithms

Let’s create a function to list primes.

A prime has exactly two positive divisors. The candidates `1↦10` are the
numbers 1 to 10. `|⊗` is the outer product of remainders. `⍨` passes `n`
as both arguments. Each row below marks the multiples of one candidate:

``` bpl
n←1↦10
0=|⊗⍨n
```

    $t $t $t $t $t $t $t $t $t $t
    $f $t $f $t $f $t $f $t $f $t
    $f $f $t $f $f $t $f $f $t $f
    $f $f $f $t $f $f $f $t $f $f
    $f $f $f $f $t $f $f $f $f $t
    $f $f $f $f $f $t $f $f $f $f
    $f $f $f $f $f $f $t $f $f $f
    $f $f $f $f $f $f $f $t $f $f
    $f $f $f $f $f $f $f $f $t $f
    $f $f $f $f $f $f $f $f $f $t

`+⌿` sums down the rows, counting each candidate’s divisors:

``` bpl
+⌿0=|⊗⍨n
```

    [1 2 2 3 2 4 2 4 3 4]ₓ

`2=` marks the primes. Replicate (`#`) keeps the items of `n` that are
marked:

``` bpl
2=+⌿0=|⊗⍨n # n
```

    2 3 5 7

A dfn names its argument `⍵`. Given the candidates `↦50`, the numbers 1
to 50, it lists the primes up to 50:

``` bpl
{2=+⌿0=|⊗⍨⍵ # ⍵}↦50
```

    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

Finally, name it. The trailing `↦` generates the candidates:

``` bpl
primes ← {2=+⌿0=|⊗⍨⍵ # ⍵}↦
primes 50
```

    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

The built-in prime glyph `⍭` returns the prime at a position, counting
from 0. Applied to `⍳15`, it produces the same list directly:

``` bpl
⍭ ⍳15
```

    [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47]ₓ

The fibonacci sequence:

``` bpl
{⍵,+/¯2↑⍵}⍣15 [1 1]
```

    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Explanation:

1.  `[1 1]`: Initial seed (first two Fibonacci numbers). Without the
    brackets, `15 1 1` would be one vector.
2.  `{⍵,+/¯2↑⍵}`: Function that appends the sum of the last two items
3.  `⍣15`: Apply the function 15 times

## Labelled arrays

An array can have keys for its positions and names for its axes. BPL has
no separate table type. Here `axes` maps each axis name to that axis’s
position keys, in axis order. `axes:` then labels the rows by city and
the columns by month:

``` bpl
axes←["city":"NY" "LA";"month":"Jan" "Feb" "Mar"]
sales←axes:[10 20 30⋄40 50 60]
sales
```

       Jan Feb Mar
    NY  10  20  30
    LA  40  50  60

`⌷` selects by key, with one key for each axis. A single key selects a
row. `⍠` applies a function along the axes named by its right operand.
Summing over `month` gives one total for each city, keyed by city.

``` bpl
"LA"⌷sales
"LA" "Feb"⌷sales
+/⍠"month" sales
```

    ["month":3]⍴["Jan":40 "Feb":50 "Mar":60]

    50

    ["city":2]⍴["NY":60 "LA":150]

Unlabelled arrays keep their usual positional behaviour. See [Axis
keys](keyed.ipynb) for construction, updates and alignment rules.

## CSV and JSON

CSV headers become keys on a vector of columns. Numeric columns use
compact storage. These two orders total 101:

``` bpl
orders←•csv "price,qty
10.5,2
20,4"
+/orders.price×orders.qty
```

    101

JSON objects use the same keyed arrays. Parse a record and select a
field:

``` bpl
record←•json "{""name"":""Ada"",""scores"":[8,9,10]}"
record.name
+/record.scores
```

    Ada

    27ₓ

`•json⁻¹` writes the record back as JSON text. For files, compose with
`•nget` and `•nput`, as in `•csv •nget "orders.csv"`. See [files, CSV
and JSON](data.ipynb) for dialect and file options.

``` bpl
•json⁻¹ record
```

    {"name":"Ada","scores":[8,9,10]}

## Regex

`•r` compiles a regular expression into two functions: `matches` gives a
table of each match’s text, position and groups, and `replace` replaces
each match:

``` bpl
codes←•r "([A-Z]+)-([0-9]+)"
codes.matches "AB-12 CD-3"
"$2:$1" codes.replace "AB-12 CD-3"
```

    ["text":["AB-12" "CD-3"] "position":[0 6]ₓ "groups":("AB" "12"⋄"CD" "3")]

    12:AB 3:CD

## Probability distributions

Construct a standard normal, then evaluate its CDF and quantiles.
Distribution methods accept arrays:

``` bpl
normal←•distribution "normal"
normal.cdf ¯1 0 1
normal.quantile 0.025 0.5 0.975
```

    0.1586552539 0.5 0.8413447461

    ¯1.959963985 0 1.959963985

Sampling takes a shape. A generator from `•rand` on the left makes the
draws repeatable:

``` bpl
•rand1 normal.sample 2 3
```

    0.8439986136  0.7155607127 ¯1.915871444 
    0.4524964704 ¯0.8157912067  0.3583251372

For discrete distributions, `density` gives probability mass. A fair
coin tossed twice has probabilities ¼, ½, ¼ for zero, one or two heads:

``` bpl
coin←2 0.5 •distribution "binomial"
coin.density 0 1 2
```

    0.25 0.5 0.25

See [distributions](distributions.ipynb) for the 17 families, and
[regex](regex.ipynb) for captures and replacement options.

## Learning APL

To start learning APL, follow the [17 video
series](https://forums.fast.ai/t/apl-array-programming/97188) run by
Jeremy Howard, and have a look at the [study
notes](https://fastai.github.io/apl-study/apl.html). These use Dyalog
APL. The main differences from Dyalog are that indices count from 0,
brackets are used to write vectors, and spaces group expressions. See
the [Language overview](overview.ipynb).
