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)

We take advantage of a property of q’s indexing: If you request an item from a list (or a dictionary, for that matter) using an index that is out of range, q returns the null item for the list’s type.

q)x: 1 2 3
q)x 3

Thus, we can take the item whose corresponding null we want, make a list from it, and then access that list with an out-of-range index:

q)NullOf: {[item] enlist[item] 1}
q)NullOf 1
q)(::) ~ NullOf {x*x}
q)null NullOf (.z.D; 1e; ” “; type “foo”)

Remember, there is no null list. If you pass a list to NullOf, you get the empty list of the corresponding type:

q)NullOf 1 2 3

See also: .Q.ty

A view is syntactic sugar for a canned query. Unless the view is referenced, it does not expend computational resources.

See also: view, views, :: , .z.b and \b