This article summarizes a lecture I performed several times over the years as part of 1010data’s summer intern training program, discussing indexing and function application. These features are among the great pearls of K, and an essential component of practical programming. Examples have been tweaked slightly to reflect the behavior of oK (which represents the k6 dialect) rather than k3, but most of the discussion applies to all K dialects.

K offers several ways to access an element from a list or vector by index:

```
t:11 22 33 44 55 66;
t[4] / subscripting
55
t 4 / juxtaposition
55
t@4 / the 'at' verb
55
t . 4 / the 'dot' verb
55
```

(Take special note of the need for whitespace between `.`

and `4`

: without the space, K would interpret `.4`

as a decimal number!)

At first glance, these all seem equivalent. How are they different? Indexing in K generalizes to vectors:

```
t[1 2 3 2 1]
22 33 44 33 22
t 1 2 3 2 1
22 33 44 33 22
t@1 2 3 2 1
22 33 44 33 22
```

This is important for the common idiom `@<`

for sorting:

```
u:33 27 19 14 99 50;
<u
3 2 1 0 5 4
u@<u
14 19 27 33 50 99
```

However, `.`

doesn’t seem to work like the other approaches when indexing by a vector:

```
t . 1 2 3 2 1
rank error
t . 1 2 3 2 1
^
```

Let’s focus on bracket-indexing, for the sake of consistency, and come back to the alternatives later.

Consider indexing into a matrix. K matrices are a list of lists, so the “outer” dimension is the row and the “inner” dimension is the column:

```
m:("ABCD"
"EFGH"
"IJKL"
"MNOP")
m[1] / row
"EFGH"
m[1;3] / row ; column
"H"
m[1 2] / rows
("EFGH"
"IJKL")
m[1 2;0 2] / rows ; columns
("EG"
"IK")
m[0 2 0 2;1 3 1 3]
("BDBD"
"JLJL"
"BDBD"
"JLJL")
```

When indexing with brackets, an empty dimension is a “wildcard”:

```
m[;1 2] / all rows, columns 1 and 2
("BC"
"FG"
"JK"
"NO")
m[1 2;] / equivalent to m[1 2]
("EFGH"
"IJKL")
```

In general, juxtaposition of a value and an index is equivalent to the verb `@`

(apply):

```
m 1 2
("EFGH"
"IJKL")
m@1 2
("EFGH"
"IJKL")
```

Square brackets are equivalent to the verb `.`

(apply-at-depth):

```
m[1 2;1 3]
("FH"
"JL")
m . (1 2;1 3)
("FH"
"JL")
```

And `@`

is equivalent to `.`

if we enclose its argument, restricting it to operate on the outermost dimension:

```
m@1 2
("EFGH"
"IJKL")
m . ,1 2
("EFGH"
"IJKL")
```

Hopefully this makes the error from `t . 1 2 3 2 1`

clear: the value `t`

does not have a sufficient *rank* (count of dimensions) to index-at-depth through 5 dimensions!

You may have noticed that brackets are also used for calling functions. What gives?

```
f:{x+100*y};
f[4;9]
904
```

In point of fact, we can call a function in the same four ways we can index a list:

```
{2+x}[4] / subscripting
6
{2+x}4 / juxtaposition
6
{2+x}@4 / the 'at' verb
6
{2+x}. 4 / the 'dot' verb
6
```

In K, indexing and calling functions (application) are identical *ideas*, so they have identical syntax. This is a *profound* symmetry!

What happens if we use a “wildcard” index on a function or don’t specify every argument? We get back a “projected” function which remembers the arguments that have been supplied already but still needs values for any empty slots:

```
f[4]
{[x;y]x+100*y}[4;]
f[;9]
{[x;y]x+100*y}[;9]
(f[;9])4
904
```

In functional languages the process of producing a new function from an existing one by supplying a fixed value for some arguments is called partial application. The behavior of K’s bracket syntax and projection provides an unusually flexible mechanism for applying any subset of a function’s arguments in any order.

Note that this works on built-in verbs, too:

```
,[;"foo"]
,[;"foo"]
,[;"foo"]"bar"
"barfoo"
```

Consider the parallels between a “partially sliced” matrix:

```
b:{x{x+2*y}/:\:x}[!4]
(0 2 4 6
1 3 5 7
2 4 6 8
3 5 7 9)
b[1]
1 3 5 7
b[;2]
4 5 6 7
b[1;2]
5
```

And a partially-applied dyadic function:

```
f:{x+2*y};
f[1]'!4
1 3 5 7
f[;2]'!4
4 5 6 7
f[1;2]
5
```

In a very real sense, K data structures *are* functions, and functions *are* (a shorthand for) data structures! In the same way that we can project a column out of a table, we can project a specialized function out of a general one:

```
customerNames:customers`name
getSales:getTable[(user;password;sessionid);`sales;]
```

Most dialects of K do not feature lexical closure for functions; functions only have access to global variables, their own local variables, and their own direct arguments. Projections offer an explicit way to package a function with arguments such that they travel together. By projecting a complex function down to just one or two missing arguments, it becomes easy to use with K adverbs, many of which expect to manipulate a monad or dyad.

K is highly parsimonious in its featureset, so the fact that it offers four ways to handle indexing suggests how important these alternatives are!

Juxtaposition is the least visually “noisy”, and is typically preferred when it can do the job:

```
bar[foo[23]] / bracketed (unnecessarily nested)
bar@foo@23 / 'at' verb (somewhat less readable)
bar foo 23 / juxtaposed (best)
```

The `@`

verb is often useful as an argument to an adverb, or when juxtaposition would be ambiguous:

```
(#:;*:)@\:/:("Apple";"Banana";"Cherry")
((5;"A")
(6;"B")
(6;"C"))
(11 22 33)44 55 66?x / juxtaposition of two adjacent vector literals requires parens
11 22 33@44 55 66?x / the 'at' verb is more concise
```

Bracket-indexing is the most natural way to handle multiple function arguments or indexing dimensions. In older dialects of K (k2, k3), projection was *syntactic*, and only bracket-indexing produced this effect. Newer dialects (k5, k6) tend to make projection *semantic*: any form of application which leaves “missing slots” will produce a projection:

```
{x+100*y}2
{[x;y]x+100*y}[2;]
{x+100*y}@2
{[x;y]x+100*y}[2;]
{x+100*y}.(;2)
{[x;y]x+100*y}[;2]
```

The `.`

verb is the least common of the above in everyday programming. Sometimes it’s handy as a suffix when you’d like a monadic function that consumes a tuple and immediately destructures it into individual arguments:

```
p2c: {x*(sin y;cos y)}. / polar (r,a) to cartesian (x,y) coordinates
```

As always in K, aim for formulations which are *concise*, *flat*, and *internally consistent*.

- Indexing and function application are identical, interchangeable concepts in K.
- There are four notations for indexing and application: juxtaposition, brackets,
`@`

and`.`

, of which`.`

is the most general. - Providing too many indices is typically a
`rank`

error, whereas providing too few indices produces a projection.