Overloading the operator in functional amend - kdb

How to overload an operator in functional amend?
s:string (`a1`b2`c3)
b:string til 2
using functional amend with , gives
q)#[s;0 2;,;b]
("a10";"b2";"c31")
I want to overload the , (append) to prefix the content of list b to list a like :
("0a1";"b2";"1c3")

You need to use a custom function {y,x} instead if , to achieve this
#[s;0 2;{y,x};b]
("0a1";"b2";"1c3")
Please note that here , is a dyadic function; Any other dyadic function e.g. {y,x} can be used in functional amend with valance 4.
The general format of functional amend is following, where f is dyadic function
#[L;I;f;y]
q)#[1 2 3 4 ;1 3;*;5 ] // * is dyadic function {x*y}
1j, 10j, 3j, 20j
and when f is monadic function
#[L;I;f]
q)#[1 2 3 4 ;1 3;neg ]
1j, -2j, 3j, -4j

Related

Clojure-esque threading macro?

How to implement, or is there an implementation of Clojure-like threading macros, namely thread-first (->) and thread-last (->>)?
Example:
# equivalent of sum(1, 2)
#thread-first 1 sum(2)
# equivalent of any(map(isequal(1), [1,2,3]))
#thread-last [1,2,3] map(isequal(1)) any
Julia has pipelining, but in general the |> operator only allows one-argument functions. In Clojure, the thread-first and thread-last arguments insert the argument at the beginning or end of multiple arguments in the function.
You do have the #> and #>> macros in Lazy.jl:
https://github.com/MikeInnes/Lazy.jl#macros
These do thread-first and thread-last, but with different syntax. See the Lazy.jl docs. Example of thread-last:
#>> 1:10 collect filter(isodd) square.() reduce(+)
165
example of thread-first:
#> 6 div(2)
3

Iterate (/) a multivalent function

How do you iterate a function of multivalent rank (>1), e.g. f:{[x;y] ...} where the function inputs in the next iteration step depend on the last iteration step? Examples in the reference manual only iterate unary functions.
I was able to achieve this indirectly (and verbosely) by passing a dictionary of arguments (state) into unary function:
f:{[arg] key[arg]!(min arg;arg[`y]-2)}
f/[{0<x`x};`x`y!6 3]
Note that projection, e.g. f[x;]/[whilecond;y] would only work in the scenario where the x in the next iteration step does not depend on the result of the last iteration (i.e. when x is path-independent).
In relation to Rahul's answer, you could use one of the following (slightly less verbose) methods to achieve the same result:
q)g:{(min x,y;y-2)}
q)(g .)/[{0<x 0};6 3]
-1 -3
q).[g]/[{0<x 0};6 3]
-1 -3
Alternatively, you could use the .z.s self function, which recursively calls the function g and takes the output of the last iteration as its arguments. For example,
q)g:{[x;y] x: min x,y; y:y-2; $[x<0; (x;y); .z.s[x;y]]}
q)g[6;3]
-1 -3
Function that is used with '/' and '\' can only accept result from last iteration as a single item which means only 1 function parameter is reserved for the result. It is unary in that sense.
For function whose multiple input parameters depends on last iteration result, one solution is to wrap that function inside a unary function and use apply operator to execute that function on the last iteration result.
Ex:
q) g:{(min x,y;y-2)} / function with rank 2
q) f:{x . y}[g;] / function g wrapped inside unary function to iterate
q) f/[{0<x 0};6 3]
Over time I stumbled upon even shorter way which does not require parentheses or brackets:
q)g:{(min x,y;y-2)}
q){0<x 0} g//6 3
-1 -3
Why does double over (//) work ? The / adverb can sometimes be used in place of the . (apply) operator:
q)(*) . 2 3
6
q)(*/) 2 3
6

Unable to pass multiple arguments to each function in kdb

How do i passed 2 variables to a lambda function, where x is a number and y is a symbol.
I have written this, but it wouldn't process
{[x;y]
// some calculation with x and y
}
each ((til 5) ,\:/: `a`b`c`d`f)
It seems to be complaining that i am missing another arg.
Here's an example that I think does what you're looking for:
q){string[x],string y}./: raze (til 5) ,\:/: `a`b`c`d`f
The issue with your example is that you need to raze the output of ((til 5) ,\:/: `a`b`c`d`f) to get your list of 2 inputs.
Passing a list of variables into a function is accomplished using "." (dot apply) http://code.kx.com/q/ref/unclassified/#apply
.e.g
q){x+y} . 10 2
12
In my example, I've then used an "each right" to then apply to each pair. http://code.kx.com/q/ref/adverbs/#each-right
Alternatively, you could use the each instead if you wrapped the function in another lamda
q){{string[x],string y} . x} each raze (til 5) ,\:/: `a`b`c`d`f
Instead of generating a list of arguments using cross or ",/:\:" and passing each of these into your function, modify your function with each left each right ("/:\:") to give you all combination. his should take the format;
x f/:\: y
Where x and y are both lists. Reusing the example {string[x],string y};
til[5] {string[x], string y}/:\:`a`b`c`d
This will give you a matrix of all combinations of x and y. If you want to flatten that list add a 'raze'

q - Applying arbitrary function while zipping

in q the dyadic zip operation is done by '. I.e.
l1:("a1";"a2")
l2:("b1";"b2")
(l1,'l2)~("a1b1";"a2b2")
I parse this ' as a dyadic operator '[g;l2] where g is a projection of some dyadic function on lists onto a monadic function, e.g. g:,[l1;].
So if we want to perform any other map apart from , during the zipping operation, I would redefine g.
However, '[g;l2] does not give me the expected list output but returns func
The question is: how do I apply arbitrary maps during the zipping operation? E.g. how do I do something like l1 f' l2 where in the example f:, but in general f some dyadic operator on to list items?
Thanks for the help
how do I apply arbitrary maps during the zipping operation?
Like this:
q)f:{x+y}
q)f'[10*x;x:til 5]
0 11 22 33 44
If you like the infix notation, you can also do
q)(10*x) f' til 5
0 11 22 33 44
Note that '[g;l1] is a composition. If you want to create a projection, do
q)g:,'[l1;]
q)g l2
"a1b1"
"a2b2"

KDB+/Q: About unused parameters in inner functions

I have this function f
f:{{z+x*y}[x]/[y]}
I am able to call f without a 3rd parameter and I get that, but how is the inner {z+x*y} able to complete without a third parameter?
kdb will assume, if given a single list to a function which takes two parameters, that you want the first one to be x and the remainder to be y (within the context of over and scan, not in general). For example:
q){x+y}/[1;2 3 4]
10
can also be achieved by:
q){x+y}/[1 2 3 4]
10
This is likely what's happening in your example.
EDIT:
In particular, you would use this function like
q){{z+x*y}[x]/[y]}[2;3 4 5 6]
56
which is equivalent to (due to the projection of x):
q){y+2*x}/[3 4 5 6]
56
which is equivalent to (due to my original point above):
q){y+2*x}/[3;4 5 6]
56
Which explains why the "third" parameter wasn't needed
You need to understand 2 things: 'over' behavior with dyadic functions and projection.
1. Understand how over/scan works on dyadic function:
http://code.kx.com/q/ref/adverbs/#over
If you have a list like (x1,x2,x3) and funtion 'f' then
f/(x1,x2,x3) ~ f[ f[x1;x2];x3]
So in every iteration it takes one element from list which will be 'y' and result from last iteration will be 'x'. Except in first iteration where first element will be 'x' and second 'y'.
Ex:
q) f:{x*y} / call with -> f/ (4 5 6)
first iteration : x=4, y=5, result=20
second iteration: x=20, y=6, result=120
2. Projection:
Lets take an example funtion f3 which takes 3 parameters:
q) f3:{[a;b;c] a+b+c}
now we can project it to f2 by fixing (passing) one parameter
q) f2:f3[4] / which means=> f2={[b;c] 4+b+c}
so f2 is dyadic now- it accepts only 2 parameters.
So now coming to your example and applying above 2 concepts, inner function will eventually become dyadic because of projection and then finally 'over' function works on this new dyadic function.
We can rewrite the function as :
f:{
f3:{z+x*y};
f2:f3[x];
f2/y
}