Search code examples
kdbk

Expressions/operator precedence in Amend At and in function parameters


I always thought that in q and in k all expressions divided ; evaluated left-to-right and operator precedence inside is right-to-left.

But then I tried to apply this principle to Ament At operator parameters. Confusingly it seems working in the opposite direction:

$ q KDB+ 3.6 2019.04.02 Copyright (C) 1993-2019 Kx Systems
q)@[10 20 30;g;:;100+g:1]
10 101 30

The same precedence works inside a function parameters too:

q){x+y}[q;10+q:100]
210

So why does it happend - why does it first calculate the last one parameter and only then first? Is it a feature we should avoid?

Upd: evaluation vs parsing. There could be another cases: https://code.kx.com/q/ref/apply/#when-e-is-not-a-function

q)@[2+;"42";{)}]
')
  [0]  @[2+;"42";{)}]
q)@[string;42;a:100] / expression not a function
"42"
q)a // but a was assigned anyway
100
q)@[string;42;{b::99}] / expression is a function
"42"
q)b // not evaluated
'b
  [0]  b
       ^

Solution

  • The semicolon is a multi-purpose separator in q. It can separate statements (e.g. a:10; b:20), in which case statements are evaluated from left-to-right similar to many other languages. But when it separates elements of a list it creates a list expression which (an expression) is evaluated from right-to-left as any other q expression would be.

    Like in this example:

    q)(q;10+q:100)
    110 100
    

    One of many overloads of the dot operator (.) evaluates its left operand on a list of values in its right operand:

    q){x+y} . (q;10+q:100)
    210
    

    In order to do so a list expression itself needs to be evaluated first, and it will be, from right-to-left as any other list expression.

    However, the latter is just another way of getting the result of

    {x+y}[q;10+q:100]
    

    which therefore should produce the same value. And it does. By evaluating function arguments from right-to-left, of course!

    A side note. Please don't be confused by the conditional evaluation statement $[a;b;c]. Even though it looks like an expression it is in fact a statement which evaluates a first and only then either b or c. In other words a, b and c are not arguments of some function $ in this case.