KX Community

Find answers, ask questions, and connect with our KX Community around the world.
KX Community Guidelines

Home Forums kdb+ kdb+ paster

  • kdb+ paster

    Posted by cillianreilly on November 16, 2022 at 12:00 am

    Here is a utility function I wrote to allow multi-line pasting into the kdb+ console. I find this very helpful when debugging or stepping through code, as I can copy in chunks of code, rather than line by line. I keep it in my q.q file.

    I’d seen this idea once or twice, but I never really liked those implementations. Most used a while loop (or worse, the while keyword) or prompted for some string input to terminate. This version uses convergence on the input string and the number of lambdas in the input. (i.e. it won’t converge if you’ve opened a function and not closed it – this handles the edge case of blank lines inside functions). Entering a blank line, with no currently open lambdas, terminates the program.

    paste:{ value // evaluate gathered input ({ $[(“”~r:read0 0)and not x; // read input, check current function count (x;””); // return initial state, halt convergence (x+/124-7h$”{}”inter r; // increment/decrement function count y,` sv enlist r) // append latest input, host line separator ] }.)/ // apply to 2 item initial state and converge [(0;””)] // initial state }

    Some interesting bits:

    1. read0 0 prompts for input and reads from STDIN
    2. x+/124-7h$”{}”inter r; increments or decrements the function count. The ASCII values for “{” and “}” were remarkably convenient for tracking. This allows for blank lines inside functions, without terminating convergence.

    q)124-7h$"{}" 
    1 -1

    3. ` sv enlist r; When the left argument is a null symbol, and the right argument is a list of strings, joins the strings on the host line separator. This appends a newline to the input – deals with comments in the code.

    q)` sv enlist "//comment" 
    "//comment\r\n"

    Here’s an example.

    q)paste[] test:{ x:x*4; // comment x-2 } 
    q)test { x:x*4; // comment x-2 } 
    q)test til 10 
    -2 2 6 10 14 18 22 26 30 34

    For those without comments or blank lines in their code, the very succinct forms below can be used instead.

    {value{x,read0 0}/[""]} k){.{x,0::0}/[""]}

    This does not work inside a context with d. If you want to define something in a namespace, use the full context name in the input.

    cillianreilly replied 8 months, 2 weeks ago 1 Member · 1 Reply
  • 1 Reply
  • cillianreilly

    Member
    November 19, 2022 at 12:00 am

    Always room for improvement. There is no need to pass the number of open lambdas between each iteration when that can be easily checked during each iteration. Now there is no need to pass a 2 item list, we can just converge on the input string itself. The true condition in the above version is also a bit suspect, this is cleaner.

    paste:{value{$[(“”~r:read0 0)and not sum 124-7h$x inter”{}”;x;x,` sv enlist r]}/[“”]}

    @SJT, happy to write this up for Awesome Q.

Log in to reply.