cancel
Showing results for 
Search instead for 
Did you mean: 

Why does the amend form of dot operator creates a projecttion like the line in .u.rep: (.[;();:;].)each x? Shouldn't it apply the function to every item in x since we do "each"? Thank you!

kdb_newbie
New Contributor II
 
1 ACCEPTED SOLUTION

gyorokpeter-kx
Contributor
Contributor

This has to do with the behavior of the ' operator (which is each is a wrapper for).

If we have p:.[;();:;] , p is a binary function, as it is a projection with two elided arguments. The ' operator modifies a function to go elementwise on its arguments - and the resulting function has the same arity as the original one. So p' is also a binary function. Applying p' to a single object (in this case a two-element list) only gives it one argument, the other is still missing, so the result is a projection.

In fact each is a wrapper that only works with unary functions. You get the same behavior whenever you try to use each with a non-unary function on the left side. You can only make non-unary functions behave elementwise by directly using the apostrophe and passing the necessary number of arguments.

If we add a dot after the projection: p2:.[;();:;] . , this changes the structure of the expression. The main operator is now the dot, and it is projected with the left argument p. Since the dot is a binary function, projecting it with one argument creates a unary function. Now you can use each with the unary function and a list. And then the dot will do what you would expect - invoke the function on the left (which is p) with the elements on the list on the right as arguments, and since we are iterating over the original list, those arguments will be a table name and an empty table. The original projection p is a fancy way of overwriting a variable. It would work just as well with set

.[set]each x

has the same effect of assigning the empty table values to the respective tables.

 

View solution in original post

3 REPLIES 3

gyorokpeter-kx
Contributor
Contributor

Can you provide more details such as what you are trying to achieve and what the value of x is?

A projection is created whenever there is an elided argument in the argument list, no matter what the argument list is being applied to. In fact this allows you to create projections that have no useful purpose such as f:{x}[;;2] which will always either return another projection or throw a 'rank error.

I am trying to understand the .u.rep function in r.q:
.u.rep: (.[;();:;].)each x
Shouldn't it apply the function to every item in x since we do "each"; it still needs the right-most dot to apply the function to each pair of x
Here, x: x:((`trade;([]time:`time$();sym:`$();price:`float$();size:`int$()));(`quote;([]time:`time$();sym:`$();bid:`float$();bsize:`int$();ask:`float$();asize:`int$())));

Why does it create a projection? (without the right-most dot, it's a projection):
.u.rep: (.[;();:;])each x

gyorokpeter-kx
Contributor
Contributor

This has to do with the behavior of the ' operator (which is each is a wrapper for).

If we have p:.[;();:;] , p is a binary function, as it is a projection with two elided arguments. The ' operator modifies a function to go elementwise on its arguments - and the resulting function has the same arity as the original one. So p' is also a binary function. Applying p' to a single object (in this case a two-element list) only gives it one argument, the other is still missing, so the result is a projection.

In fact each is a wrapper that only works with unary functions. You get the same behavior whenever you try to use each with a non-unary function on the left side. You can only make non-unary functions behave elementwise by directly using the apostrophe and passing the necessary number of arguments.

If we add a dot after the projection: p2:.[;();:;] . , this changes the structure of the expression. The main operator is now the dot, and it is projected with the left argument p. Since the dot is a binary function, projecting it with one argument creates a unary function. Now you can use each with the unary function and a list. And then the dot will do what you would expect - invoke the function on the left (which is p) with the elements on the list on the right as arguments, and since we are iterating over the original list, those arguments will be a table name and an empty table. The original projection p is a fancy way of overwriting a variable. It would work just as well with set

.[set]each x

has the same effect of assigning the empty table values to the respective tables.