cancel
Showing results for 
Search instead for 
Did you mean: 

Function composition using common argument

JP
New Contributor III

Hi,

Newbie question I guess. To simplify, say I have 2 functions f1 & f2:

 

q) f1: {1-x%y}
q) f2: {mavg[x;y]}			/This is voluntary

 

which actually in this case, have a common argument when a composition <g> is applied, eg. :

 

q) a: til 10
q) g: f1 . (f2 . (3;a); a)
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111

 

I can't figure a compact/elegant way to specify <g> without repeating twice argument <a>.

A wrapper function can obviously do the job, though complexity grows with the number of compositions. So the question is basically: Is there an iterative (or other) way to pass an identical argument to any number of multivalent functions composed successively? 

Thx

2 ACCEPTED SOLUTIONS

cillianreilly
New Contributor III

You can do this using iteration over a list of the functions to apply.

q){z .(y;x)}[a]/[3;(f2;f1)]
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111

 Adding another function:

q)f3:+
q){z .(y;x)}[a]/[3;(f2;f1;f3)]
0n 1.5 2.5 3.333333 4.25 5.2 6.166667 7.142857 8.125 9.111111

 

View solution in original post

SJT
Valued Contributor
Valued Contributor
Q doesn’t really offer built-in combinators as liberally as its ancestor language APL does. An elegant way to compose the projections of f1 and f2? You can lose the parens…
q)c: f1[;a] f2[;a]@
q)c 3
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111
Of course, if you have to do this often, you can write your own combinator. Call it cr for curry right:
q)cr:{x[;y]}
q)c:('[;])over(f1;f2)cr\:a  / Compose over (f1[;a];f2[;a])
q)c 3
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111
Compose over a list of functions – as many as you need.

View solution in original post

3 REPLIES 3

cillianreilly
New Contributor III

You can do this using iteration over a list of the functions to apply.

q){z .(y;x)}[a]/[3;(f2;f1)]
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111

 Adding another function:

q)f3:+
q){z .(y;x)}[a]/[3;(f2;f1;f3)]
0n 1.5 2.5 3.333333 4.25 5.2 6.166667 7.142857 8.125 9.111111

 

SJT
Valued Contributor
Valued Contributor
Q doesn’t really offer built-in combinators as liberally as its ancestor language APL does. An elegant way to compose the projections of f1 and f2? You can lose the parens…
q)c: f1[;a] f2[;a]@
q)c 3
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111
Of course, if you have to do this often, you can write your own combinator. Call it cr for curry right:
q)cr:{x[;y]}
q)c:('[;])over(f1;f2)cr\:a  / Compose over (f1[;a];f2[;a])
q)c 3
0n 0.5 0.5 0.3333333 0.25 0.2 0.1666667 0.1428571 0.125 0.1111111
Compose over a list of functions – as many as you need.

JP
New Contributor III

Many thanks to you both for your inputs, very useful illustrations of projection/iteration/composition functionalities.

The function approaches work well in their current incarnation, with the small caveat (at least from my understanding) that functions to be composed must have the same rank. Relatively easy to implement argument condition handling should allow for a more generic multivalent case.  Again, thank you,

Best,

JP