Short answer:      : return_value

Unless you use : (return) or ‘ (signal) to specify otherwise, a q function returns the value of its last expression. Since functions are lists of expressions separated by semicolons, both of the following functions return 3:

q)single_expression: {3}
q)single_expression[] 3
q)last_expression: {1; 2; 3}
q)last_expression[] 3

To return a value other than that of the last expression, use : (return):

q)explicit_return: {: 3; 4}
q)explicit_return[] 3

The last expression in explicit_return (i.e., 4) is never reached.

Meanwhile, if a function that does not return via : (return) (or ‘ (signal)) does not have a final expression (i.e, no expression after its last semicolon), that function returns a generic null:

q)no_return: {3; }
q)no_return[] q)null no_return[] 1b
q)type no_return[] 101h
q)no_return[] ~ (::)

Lastly, functions can exit in two other ways:

1. Calling the exit function:

q)die: {exit 0}
q)die[] $

(By the way, you can add code to run automatically at exit using .z.exit.)

2. Signaling an error:

q)signal: {‘ “oops”}
q)signal[] ‘oops

See this related faq for more information on the use of ‘ (signal)

You can enable error trapping via the -e command line option at kdb start-up:

$ q -e 1

or from the q console

q)\e 1

Upon an error, kdb halts and outputs the body of the function (.z.s (self)) in which the error occurred as well as an error message. You are free to inspect the values of any global or local variables to try to diagnose the source of the problem. At this point you have the following options:

  • type (single quote) to pop the stack.
  • type :(colon) to resume execution
  • type \(slash) to exit debug mode

There is no ability step into a function call or move up and down the stack.