# Vocabulary/curlylf

>>
<< ` `
Down to: Dyad ` `
Back to: Vocabulary
Thru to: Dictionary

`{ y`Catalogue

Rank 1 *-- operates on lists of y, producing a result of variable shape for each one --*
WHY IS THIS IMPORTANT?

Combines items from the atoms inside a boxed list to form a *catalogue*.

{ 0 1 ; 7 8 9 +---+---+---+ |0 7|0 8|0 9| +---+---+---+ |1 7|1 8|1 9| +---+---+---+

### Common uses

Form the Cartesian Product of two lists, `x` and `y`

CP=: {@(,&<) NB. example from Voc 0 1 CP 7 8 9 +---+---+---+ |0 7|0 8|0 9| +---+---+---+ |1 7|1 8|1 9| +---+---+---+

**Note:**
Table (`/`)
has a similar action. It is the more usual primitive to use for this task.

0 1 (<@,"0)/ 7 8 9 +---+---+---+ |0 7|0 8|0 9| +---+---+---+ |1 7|1 8|1 9| +---+---+---+

### Details

1. The shape of the contents of each box of the result is ` $y `.

2. The shape of the result is the concatenation of the shapes
of the opened atoms of y, i.e. ` ; $&.> y `.

3. The items that go into the box whose index list is `i` are selected by `i <;.1~ ; (1 {.~ #@$)&.> y`

y =. (2 2 $ 'cbmw');'ae';'tpn' {y +---+---+---+ |cat|cap|can| +---+---+---+ |cet|cep|cen| +---+---+---+ +---+---+---+ |bat|bap|ban| +---+---+---+ |bet|bep|ben| +---+---+---+ +---+---+---+ |mat|map|man| +---+---+---+ |met|mep|men| +---+---+---+ +---+---+---+ |wat|wap|wan| +---+---+---+ |wet|wep|wen| +---+---+---+ ${y 2 2 2 3 ; $&.> y 2 2 2 3 $y 3 (<1 0 1 2) { {y +---+ |men| +---+ ]s =.1 0 1 2 <;.1~ ; (1 {.~ #@$)&.> y NB. item selected from each box of y +---+-+-+ |1 0|1|2| +---+-+-+ s ({ >)"0 y NB. select them men

`x { y`From

Rank 0 _ *-- operates on atoms of x, and the entirety of y --*
WHY IS THIS IMPORTANT?

Selects the item with index `x` from the array `y` .
Negative values of `x` count back from the end of the array, which is item number `_1`.

Takes the place of *indexing an array* in other computer languages.

To replace item `x` in `y`, see: Amend (`}`)

z=: 'abcde' 1 { z b 1 _1 { z be 2 4 { z ce

Each atom of `x` specifies one selection. The selected results are assembled into an array.

i. 2 2 0 1 2 3 (i. 2 2) { z ab cd

`{ ` works with `y` of any rank.

- The items of an array are the cell one rank less than the array.
- The items of a table are lists; the items of a brick are tables.

] z=: i.3 5 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 { z 5 6 7 8 9 2 0 { z 10 11 12 13 14 0 1 2 3 4

Boxed `x` can specify indexing along multiple axes, selection of subarrays, and more.

(<2 1) { z NB. Select row 2, column 1 11 (<2 1;1 3) { z NB. Select rows 2&1, columns 1&3 11 13 6 8

### Common uses

1. Convert from an ASCII code to the corresponding byte

65 97 { a. Aa

2. Select a column from a table

] z=: i.3 5 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 {"1 z 1 6 11 (<a:;1) { z 1 6 11

3. The Foreign (`5!:5`) (Linear Representation) employs **From** (`{`) in its output when designating the position in the J-alphabet of a non-printable character, e.g. Linefeed (`LF`):

linefeed=: LF"_ type 'linefeed' +----+ |verb| +----+ 5!:5 <'linefeed' (10{a.)"_

### Related Primitives

Amend (`x m} y`)

### More Information

#### Beyond Items: Boxed x

`x { y` at its most general can select a specified subarray of `y`,
where the selected elements and their order can be controlled independently for each axis.
Since each atom of `x` is processed separately (because the left rank of (`x { y`) is `0`),
values of `x` that specify more complex indexing must be put into a single atomic **box**.

A subarray is specified by a **list of boxes** where each box contains the selector for one axis.
**The list of selectors is itself put into a box** so that it becomes an atom and is therefore usable as a left argument to `x { y`.

The selectors are applied in order:

- the first selector selects an array of _1-cells of
`y` - the second selector selects an array from each of those cells
- and so on.

A selector is a noun, each atom of which gives one selection for the axis.

- If the selector is an atom, the selected position is taken and no corresponding axis is created in the result.
- If the selector is an array, the selected positions are collected into an array of selections whose shape equals the shape of the selector.

We will use the following test array and test verb

]a =: 5 6 $ 'abcdefghijklmnopqrstuvwxyz0123' abcdef ghijkl mnopqr stuvwx yz0123 NB. Verb to show shape showshape =: 'empty' [^:(0=*@#@]) $ NB. Verb to show one selection headings =. ('Array';('Selectors','-',:' Shapes ');'Selection';'Selected Shape') showsel =: headings ,: (] ; (,: showshape L:0)@:>@[ ; { (;<) showshape@{)

To select a single atom, specify its index list

(<(<2),(<3)) showsel a +------+-------------+---------+--------------+ |Array |Selectors |Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+-------------+---------+--------------+ |abcdef|+-----+-----+|p |empty | |ghijkl||2 |3 || | | |mnopqr|+-----+-----+| | | |stuvwx||empty|empty|| | | |yz0123|+-----+-----+| | | +------+-------------+---------+--------------+

Row 2, column 3. A single atom is selected.

If a selector contains an array, the selections are arrayed along those axes:

(<(<2 1),(<2 3 5)) showsel a +------+-----------+---------+--------------+ |Array |Selectors |Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+-----------+---------+--------------+ |abcdef|+---+-----+|opr |2 3 | |ghijkl||2 1|2 3 5||ijl | | |mnopqr|+---+-----+| | | |stuvwx||2 |3 || | | |yz0123|+---+-----+| | | +------+-----------+---------+--------------+

Selecting 2 positions in the first axis, 3 in the second, to yield a 2x3 array. Note that the order of the atoms of the selector is preserved in the selection.

As usual, there is a difference between an atom and a 1-element list

(<(<,2),(<3)) showsel a +------+---------+---------+--------------+ |Array |Selectors|Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+---------+---------+--------------+ |abcdef|+-+-----+|p |1 | |ghijkl||2|3 || | | |mnopqr|+-+-----+| | | |stuvwx||1|empty|| | | |yz0123|+-+-----+| | | +------+---------+---------+--------------+

The same atom is selected, but it is part of an array (a list).

#### Complementary Indexing and Omitted Axes

If a selector is boxed, (which means it is a box within a list of boxes within another box),
it specifies all the positions **except** the ones in the opened selector.
These positions are arranged into a list, in ascending order.

The boxed selector must be an atomic box. Its contents may have any shape but each atom of the contents must be a valid index for the axis.

(<(<<1 3),(<3 4)) showsel a +------+-----------+---------+--------------+ |Array |Selectors |Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+-----------+---------+--------------+ |abcdef|+-----+---+|de |3 2 | |ghijkl||+---+|3 4||pq | | |mnopqr|||1 3|| ||12 | | |stuvwx||+---+| || | | |yz0123|+-----+---+| | | | ||+-+ |2 || | | | |||2| | || | | | ||+-+ | || | | | |+-----+---+| | | +------+-----------+---------+--------------+

The selection was all rows **except** 1 and 3, and columns 3 and 4.

To select all of an axis without knowing its length,
use complementary selection to select all positions except an empty list.
That will select everything.
Such a selector would be (`<0$0`) which happens to be the primitive `a:`:

A selector of `a:` designates an *omitted axis* which is **taken in full**.

(<(<a:),(<3 4)) showsel a +------+---------+---------+--------------+ |Array |Selectors|Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+---------+---------+--------------+ |abcdef|+---+---+|de |5 2 | |ghijkl||++ |3 4||jk | | |mnopqr|||| | ||pq | | |stuvwx||++ | ||vw | | |yz0123|+---+---+|12 | | | ||+-+|2 || | | | |||0|| || | | | ||+-+| || | | | |+---+---+| | | +------+---------+---------+--------------+

All rows, columns 3 and 4.

If there are fewer selectors than axes, the trailing axes are omitted axes and are taken in full:

(<(<<4 2)) showsel a +------+---------+---------+--------------+ |Array |Selectors|Selection|Selected Shape| | |-------- | | | | | Shapes | | | +------+---------+---------+--------------+ |abcdef|+-----+ |abcdef |3 6 | |ghijkl||+---+| |ghijkl | | |mnopqr|||4 2|| |stuvwx | | |stuvwx||+---+| | | | |yz0123|+-----+ | | | | ||+-+ | | | | | |||2| | | | | | ||+-+ | | | | | |+-----+ | | | +------+---------+---------+--------------+

All rows except 2 and 4, and all columns.

#### Singly-boxed x

If an atom of `x` contains a numeric array
rather than a list of boxes, each 1-cell of the array is an index list of a cell to be selected; the cells are arranged into an array according to the shape of `x`. This is the way to perform * scatter-indexing* of disordered cells.

In the simplest case where `>x` is a list, each atom of the list is treated as a selector.
This generates an atomic selection for as many axes as there are numbers in the list.

Remaining axes are taken in full.

This is the normal way to perform multidimensional indexing where the result is a single cell

(<2 3) { a p

Row 2, column 3.

#### Unboxed `x`

When `x` is unboxed, each atom of `x` is treated as a single selector for the first axis, with the remaining axes taken in full.
This is the case we encountered in the beginning: each atom of `x` selects an item of `y`.

#### Empty `x`

There are many ways of selecting nothing. The results are surprising, but they follow the rules for applying verbs on empty arguments.

$ '' { i. 3 4 0 4

Here there was *no selection*. The verb (`{`) was executed on a cell of fills, as (`0 { i. 3 4`). This result has shape `4`, and the frame (`0`) was prepended to give the shape of the overall result.

$ (<'') { i. 3 4 3 4

Here there was a selection with *no axes*. All axes after the last one specified are taken in full; with nothing specified, they are all taken in full, so everything is selected.

$ (0$a:) { i. 3 4 0 3 4

Again *no selection*, but now the fill-cell is `a:` and (`a: { i. 3 4`) was executed to find its shape. This result has shape `3 4`, and the frame (`0`) was prepended to give the shape of the overall result.

$ (<<'') { i. 3 4 0 4

Here there was a selection with *one axis with no values*. The corresponding axis in the result is empty, and all axes after it are taken in full.

### Details

1. `a: { y` selects all of `y`.
This follows the rules.
`a:` is a single-boxed empty list,
so it makes an atomic selection from no axes,
and then takes the remaining axes in full; that is, all axes are taken in full.

2. An atom has one item, which can be selected.

0 _1 { 5 5 5

If the selector from an atomic `y` is boxed, its contents must be empty.

3. An index *i* for an axis of length *n* must be in the range (*-n*)≤*i*<*n*.
This restriction holds even if the selector is complementary.

4. A selector may be a noun of any rank, not just an atom or a list. The selected positions are collected into an array using the shape of the selector, with each atom of the selector replaced by its selection.

5. The shape of the result is the concatenation of the shapes of all the selectors,
after `x` has been put into selector form (i.e. a box containing a list of boxed selectors)
and all omitted and complementary axes have been replaced with equivalent lists.

6. `x (<<<m)} y`, which specifies complementary indexing, sorts `m`. Because `m` is usually short or in order, *insertion sort* is used. If you have large unordered `m`, you should sort it first.

### Use These Combinations

Combinations using `x { y` that have exceptionally good performance include those shown in Selections and Sorting and Ordering, as well as the following:

**What it does****Type;**

**Precisions;**

Ranks**Syntax****Variants;**

**Restrictions****Benefits;**

**Bug Warnings**Operations on a flattened array `x ({ ,) y`

`x ({. ,) y`

`x (}. ,) y`

`x (e. ,) y`

`f/@, y`

(`f`is any verb)or `@:``&``&:`in place of`@`Avoids copying the array to compute ( `,y`)

Follow a chain of variable-length records integer `x`and`y``{&x^:a: y`

`x {~^:a: y``<_`in place of`a:`Produces list of starting positions. Limit all values of `x`to at most`#x`, then append`_1`to the end of`x`. Discard the final starting position of`_1`.