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;]
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
.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