Miscellaneous

Namespace

You can think of a namespace as a package or a module in python.
There are two ways to work with namespaces: the \d method and the fully qualified method.

            q) a: 1
            
            // \d method
            q) \d .myNamespace              // create a namespace
            q.myNamespace) a: 2             // notice how the prompt changes to q.myNamespace
            q.myNamespace) a
            2
            q) \d .                         // go back to the root namespace
            q) a
            1

            // fully qualified method
            q) .myNamespace2.a: 3           // create a namespace
            q) @[`.myNamespace2; `a; :; 4]  // equivalent functional form, but namespace must exist first
            q) .myNamespace2.a
            4
            q) a
            1 
        
Difference between the two methods is To demonstrate the difference

            q) a: 1

            // \d method cannot access global variables in the root namespace
            q) \d .myNamespace
            q.myNamespace) f:{1+a}          // this will fail because a isn't available here
            q.myNamespace) f:{1+get`..a}    // unless you use get to access `. namespace
            // but is able to access variables in the same namespace
            q.myNamespace) b: 100
            q.myNamespace) f2:{1+b}         // this is okay

            // fully qualified method can access global variables in the root namespace
            q) .myNamespace2.f:{1+a}        // this is okay
            // but not able to access variables in the same namespace
            q) .myNamespace2.b: 100
            q) .myNamespace2.f2:{1+b}       // this will fail because b is not available here
        

Scripting

Scripting in KDB is easy, just save your code in a q file and load it in a q session using \l filename.q.

Passing arguments

Three ways to pass arguments to a KDB script. First way is to pass arguments in a q session when calling the script:

            q) name:"Alice"
            q) \l myscript.q   // in myscript.q, you can access the variable name
        

Second way is to use .z.x. The arguments will be unformatted as a list of strings. You don't need to run the script in a q session.

            system["env QHOME=/opt/kx/q q myscript.q -name Alice -age 30"]
        
In the script myscript.q, you can access the arguments using .z.x. In this example, the output will be: (\"-name\";\"Alice\";\"-age\";\"30\")
Third way is to use .Q.opt .z.x this will return a formatted dictionary of arguments.
Using the same example, the output will be (`name`age)!(\"Alice\";\"30\")

Hiding source code

If you only want the user to be able to run the script, but not execute individual functions defined in the script, you can use the following method:

            \_ myscript.q       // this will hide the source code
            \l myscript.q_      // this will load the hidden script
        

Debugging

Breakpoints

There is no breakpoint in KDB q, but there are two ways you can simulate the behavior.
Either just return the value you want to evaluate, or raise an error, and then debug in the break mode

            q) myFunc:{[var1; var2]
                    // some statements
                    var1+var2;
                    `break; // break here
                    // more statements
                }
            q) g[x;y]
            `break
            // now you are in the break mode, note the double parenthesis here
            q)) var1 // you'll be able to evaluate runtime values
            // exit the break mode with a slash \
            // if it's a nested break mode, you can check which layer you're in by
            q))) .z.s
            // if you want to go up a layer, can either use single slash, or return something
            q))) :1
            q)) // up a layer, one less parenthesis
        

Backtraces

Since KDB 4.0, you can use .Q.bt[] to dump the backtrace to stdout at any point during runtime.

            q) add:{x+y}
            q) addTwo:{a: add[1;2]; b:add[3;`four]}
            q) addTwo[]
            `type
            q)) .Q.bt[]
            >>[2] add{x+y}
              [1] addTwo:{a: add[1;2]; b:add[3;`four]}
                                         ^
              [0] addTwo[]
                  ^