Skip to content

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)
You can project a function with infix syntax by omitting the right argument.
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;]
It is good style to 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
Above, although +\ 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
Above the 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\""
Above, .[{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>"
From eac we can project markup functions for common HTML elements.
img:eac["img";;""]
pp:eac["p";"";]           / plain para
As eac is not a primitive, we include trailing empty items in the argument list.


Exercises

  1. FIXME