4

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?

zrb
  • 851
  • 7
  • 16

2 Answers2

6

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

terrylynch
  • 11,844
  • 13
  • 21
  • That was helpful, but didn't answer the original question – zrb Aug 02 '16 at 14:24
  • Agreed - you can see the function is not even being called. `q)({'stop;z+x*y}[2])/[10]` just returned 10 and doesn't hit the break point. I would have expected a projection returned, rather than the argument just being returned? – jgleeson Aug 02 '16 at 14:30
  • I think it does answer the question no?! See my edits – terrylynch Aug 02 '16 at 14:44
  • I think the issue is that in the user's case, y is an atom. At least that's what I thought. When you run his function y is being returned and the function is not being called. – jgleeson Aug 02 '16 at 14:48
  • 1
    Ah, ok well in that case it's just returning the seed as first result before it ever executes the function. Looks like that's the default behaviour whenever kdb is doing this special case – terrylynch Aug 02 '16 at 14:55
  • 1
    @zrb an example usage might have cleared this up, my interpretation was valid – terrylynch Aug 02 '16 at 14:56
  • 2
    That's the behavior of 'over/scan'. It returns atom if input is an atom for dyadic function without invoking the function. To get projection in output need to use form like ({x+y}/)[4;] which makes sense that new function now requires a list/atom. – Rahul Aug 02 '16 at 14:57
  • 1
    Interesting! Thanks! Agree with Terry, an example call would have been helpful. – jgleeson Aug 02 '16 at 15:01
4

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
}
Thomas Smyth - Treliant
  • 4,993
  • 6
  • 25
  • 36
Rahul
  • 3,914
  • 1
  • 14
  • 25