0

We should use square brackets when flattering all levels in list:

q)b:(1 2;(3 4;5 6);7;8)
q)raze/[b]               / flatten all levels
1 2 3 4 5 6 7 8
q)raze/b
'/
  [0]  raze/b

But why one forced to use raze/[b] for Converge syntax instead of simple raze/b?

  • Upd

Why this syntax works in k, for example {x+y}/1 2 3 but doesn't work in q?

My assumption that it's been made to prevent qbies errors when using / adverb instead of %. I think there may be a discussion about it in some dev channel, but I've found only Shakti discussion group for now at https://groups.google.com/forum/#!forum/shaktidb, and kx.com also shutted down community wiki, so I don't know where to find an additional info - asking here

  • Upd2

The / is quite overloaded in k too: see (not official ref though) https://github.com/JohnEarnest/ok/blob/gh-pages/docs/Manual.md#over - over, fixedpoint, for and while. Pretty the same as in q, right? But why the interpreter 'ban' the k syntax in q context, - is there a technical reason why q can't recognise a user intention as it k does?

egor7
  • 4,678
  • 7
  • 31
  • 55

2 Answers2

2

You don't necessarily need square brackets here. You could use

(raze/)b

if you do not want to use square brackets around b. The way you are using over ( or /) without the brackets around b requires the parenthesis around raze/b if you do not specify the initial value of the accumulator. This is because the q interpreter needs to know that you are applying raze/ to the list b rather than applying / to the list first (which is why a '/ error is thrown) then raze after (reading the code from right to left).

More info on using / can be found here: https://code.kx.com/q4m3/6_Functions/#676-over-for-accumulation

Rob Sketch
  • 361
  • 1
  • 6
  • Thank you! Now it's pretty clear that `[]` interpreted as a `raze/` param, or adverb `/` acts as a function modifier bundled with function together `(raze/)`. But the last thing - why this syntax works in `k`, for example `{x+y}/1 2 3` but doesn't work in `q`? – egor7 Feb 27 '20 at 17:21
  • Rob, what is the effect of applying `/` to the list first? How `q` interprets this? – egor7 Feb 28 '20 at 09:00
  • It is the case that the `/` is quite overloaded in q. See here for all of the syntax and semantics of `/`: https://code.kx.com/q/ref/overloads/#slash For the specific use of converge (as you are doing), it will not produce expected output unless you use `(raze/)b` or `raze/[b]`, otherwise the q interpreter will not know what to do when it reaches `/`. – Rob Sketch Feb 28 '20 at 10:05
  • 2
    @egor7 When used as an adverb a slash symbol must be adjacent to its operand, i.e. follow it, so this expression is not valid it q: `/1 2 3` as there's nothing to apply `/` to. – Igor Korkhov Feb 28 '20 at 10:10
2

The reason that, say, cos/1 works in k but not q is that q has no ambivalence. That is to say that all q operators are not overloaded on valence, as noted in section 6.1.2 in q4m.

With any of q's adverbs (each:', over:/ scan:\, prior::, eachright:/:, eachleft:\:) the resulting derivative function is interpreted by q to be dyadic, unless you uses []'s to specifically pass one argument.

For the example above q interprets cos/ as do rather than converge and so requires the left argument specifying the number of iterations (Note the results of 0 cos/ 1, 1 cos/ 1, 2 cos/ 1, etc.). The preferred way to resolve is to use []'s: cos/[1].

(cos/) 1 works because user defined functions can never use infix notation, so the expression is automatically interpreted as applying monadically. This is also why 2 (cos/) 1 fails. To resolve this you would again have to use []'s: (cos/)[2;1].

Jorge Sawyer
  • 1,331
  • 4
  • 7
  • Oh, that's pretty exhaustively! After the first reading of q4m I've marked pretty much unclear places, and one of them is exactly you've pointed out in section 6.1.2. Thank you very much! – egor7 Feb 28 '20 at 16:18