# Projection

DRAFT

Projecting a function onto an argument is a powerful aid to legibility.

A function of rank \(N\) (where \(2≤N≤8\)) can be projected upon \(M\) arguments (where \(1≤M<N\)) to produce a function of rank \(N-M\).

```
halve:%[;2] / unary projection of a binary
cube:xexp[;3] / unary projection of a binary
hus:ssr[;"_";"-"] / hyphenate underscores (unary)
rus:ssr[;"_";] / replace underscores (binary)
```

```
dbl:2* / double
inc:1+ / increment
```

## Trailing empty arguments

Trailing empty items in the argument list may be omitted.

```
dbl:*[2] / i.e. *[2;]
abc:![`a`b`c] / i.e. ![`a`b`c;]
```

**make a projection evident by including trailing empty items**, though they may safely be omitted for q primitives as above.

To project a VARIADIC function you must include empty argument items.

A function derived by applying an iterator to a binary operator is **variadic**: it may be applied as a unary or as a binary.

```
q)+\[1 2 3] / unary (bracket syntax)
1 3 6
q)+\[10;1 2 3] / binary (bracket syntax)
11 13 16
q)10+\1 2 3 / binary (infix syntax)
11 13 16
q)10+\ / i.e. +\[10]
10
```

`+\`

has infix syntax, `10+\`

is not a projection.
Instead it is equivalent to `+\[10]`

, just as `2*`

is equivalent to `*[2]`

.
To project variadic `+\`

on its left argument, use bracket syntax and **an empty argument item**;

```
q)foo:+\[10;] / projection
q)foo 1 2 3
11 13 16
```

## Bind an external constant

Projection is a good alternative to reading an external constant, provided the constant can be read when the projection is defined.

```
\d .math
PI:acos -1
.trig.aoc:{x*y*y}[PI;] / area of circle
```

*current value*of

`.math.PI`

(not a reference to it) is bound to the definition of `.math.trig.aoc`

as the fixed value of its left argument `x`

.
Subsequent changes to `.math.PI`

would not affect `.math.trig.aoc`

.
## Specific from general

FIXME: move to § Explore

You can use projection to define specific functions as variations of a general function.

Below, `eac`

is a general function for composing HTML markup, from which we project functions for marking up specific HTML elements.

```
q)d:`src`alt!("/img/logo.png";"Site logo") / attribute dictionary
q)att:{" "sv .[{string[x],"=\"",y,"\""}'] (key;value)@\:x}
q)att d
"src=\"/img/logo.png\" alt=\"Site logo\""
```

`.[{string[x],"=\"",y,"\""}']`

projects Apply on the lambda as its left argument to create a unary that is applied prefix to the two dictionary lists.
The trailing empty item in the argument listy has been omitted.
```
q)eac:{[e;a;c]:"<",e," ",att[a],$[count c;">",c,"</",e,">";"/>"]}
q)eac["img";d;""]
"<img src=\"/img/logo.png\" alt=\"Site logo\"/>"
q)eac["a";;"link text"]`href`class!("#bookmark";"links")
"<a href=\"#bookmark\" class=\"links\">link text</a>"
```

`eac`

we can project markup functions for common HTML elements.
```
img:eac["img";;""]
pp:eac["p";"";] / plain para
```

`eac`

is not a primitive, we include trailing empty items in the argument list.
## Exercises

- FIXME