Composition
DRAFT
Why use compositions?
Performance
There is a tiny performance advantage, as a composition dispenses with the almost-negligible cost of putting a lambda on the evaluation stack. (But there are use cases in which every bit helps.)
Replace explicit iterations
E.g. write (f g h::)each x
rather than f each g each h each
.
Avoid nesting lambdas
Nesting lambdas has a cost: default arguments x
, y
, and z
have different referents inside and outside the nested lambda.
Compositions help avoid this.
For example in
{x+{f g h x}each y}
x
in the inner lambda refers to y
in the outer lambda.
Instead, write
{x+(f g h::)each y}
Replace references with values
A composition binds in data values as they are at the time of composition, so there are no references to follow.
Abstraction
The Compose function lets you compose a ‘pipeline’ of functions at run time.
q)fns:({x*x};1000-;count;til)
q)cases: 1 0 3 2 / result of some test or calculation
q)foo:('[;])over fns cases
q)foo "abc"
1000 999 996
Apply or Identity?
FIXME Compare composing using @
and ::
.
Higher-rank compositions
FIXME Compositions with rank > 1