q truncates the results in stdout. How can I fix it?

To set q's console output to 80 columns wide and 24 rows high (console size), use \c:

q)\c 80 24

You can also use the $LINES and $COLUMNS environment variables to have q start up automatically with your preferred settings:

$ export LINES=40
$ export COLUMNS=120
$ q
KDB+ 2.7 2011.02.16 Copyright © 1993-2011 Kx Systems
q)\c
40 120
q)

To adjust the amount of output when access a q server via a web browser, see http page size (\C)

Lastly, you may be interested in .Q.s and .Q.s1

How do I use the timer?

If you defined a function called .z.ts, and enable q's timer with \t n then q will call .z.ts every n milliseconds:

q).z.ts: {[] show .z.T}
q)\t 500
q)07:41:15.147
07:41:15.647
07:41:16.147
07:41:16.647
07:41:17.147
\t 0
q)

As shown above, \t 0 stops the timer.

To set the timer interval, you must give \t a literal integer. What that means is that, if you want to change the timer frequency at runtime (e.g., when building a simple scheduler), the following will not work:

q)i: 500
q).z.ts: {[] show .z.T; system "t i"; i *: 2}
q)\t 500
q)07:46:47.106
07:46:47.606
07:46:48.106
07:46:48.606
\t 0
q)

Notice what happens when we enter \t i at the repl:

q)\t i
0
q)

What we've done is use \t to measure the execution time of the expression i. To get the effect we want is, fortunately, easy once you see what is going on:

q)i: 500
q).z.ts: {[] show .z.T; system "t ", string i; i *: 2}
q)\t 500
q)07:59:59.694
08:00:00.195
08:00:01.195
08:00:03.196
\t 0
q)

By passing "t ", string i instead of "t i" to system, the q interpreter sees a literal integer.

One last detail: if you decide you need to delete the definition of .z.ts, you'll need to use \x.

What environment variables do I need to know about when kdb starts up?

Here are several environment variables used by q during initialization:

You can read the value of any environment variable with the getenv function:

q)getenv `PATH
"/sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:..
q)

I know k sits under q. By porting q code to k, will it run faster?

No. The interpreter boils it down to the same bytecode.

Consider Problem 1 from Project Euler: sum the multiples of 3 and 5 which are less than 1000. You may want to try this before reading further. The problems from Project Euler are great exercises for learning q!

The code below shows one solution written in both languages; f is written in q, while g is written in k.

q)f: {(+/) distinct where (0 = x mod 3) | 0 = x mod 5}
q)\
  g: {+/?&(0={x-y*x div y}[x;3])|0={x-y*x div y}[x;5]}
  \
q)

You can see the bytecode for a function (as well as some generally more useful information, like the function's arguments) by calling value on it:

q)value f
0xa278a10a020c48a078a10a020c48462531a31b520004
,`x
`symbol$()
,`
3
k){x-y*x div y}
5
+
"{(+/) distinct where (0 = x mod 3) | 0 = x mod 5}"
q)

As you can see, when passed a function, value returns a list. The first element of that list is the function's bytecode. Now it is easy to show that f and g have the same bytecode:

q)first value f
0xa278a10a020c48a078a10a020c48462531a31b520004
q)first value g
0xa278a10a020c48a078a10a020c48462531a31b520004
q)all (first value f) = first value g
1b
q)

In q, however, you probably would have written the solution a tiny bit differently:

q)f: {sum distinct where (0 = x mod 3) | 0 = x mod 5}
q)

This results in a q version that is actually two bytes smaller and (maybe) a hair faster:

q)first value f
0xa278a10a020c48a078a10a020c48462531390004
q)first value g
0xa278a10a020c48a078a10a020c48462531a31b520004
q)\t do[100000; f til 1000]
3240
q)\t do[100000; g til 1000]
3253
q)

Thanks to Charlie Skelton from kx for pointing out errors in the original version of this article.

I defined an untyped list, but I get a type error when I add more than one element to it? How do I store mixed data in a list?

If you are defining the list's contents at the same time you declare it, this is easy:

q)list: (`sector; 47)
q)type list
0h
q)list ,: 2.7
q)list
`sector
47
2.7
q)

However, you often don't know what items are going in the list in advance. Let's try defining an empty list without specifying an element type:

q)list: ()
q)

At first, that seems to be just what we wanted:

q)type list
0h
q)

The trouble begins when we actually add elements to the list:

q)list ,: `sector
q)list ,: 47
'type
q)

What happened? Let's re-examine list's type:

q)type list
11h
q)

Now list's type is no longer 0; it has been transmuted into 11; i.e., list of symbol. The 'type error is telling us that we can't add an int to a list of symbol.

In some situations, determining the type of an empty list dynamically (i.e., when the first item is added) may be what you want. A list of symbol (or int) uses less memory that an untyped list with the same number of elements. Most operations on a typed list will be faster as well.

In this case, however, we need a way to prevent q from promoting the untyped list to a typed list. The only way to do that is to stuff the list - when you create it - with some data that can't fit into a typed list. While you could use two values of different types (as in our first example), you only need to use one value if that value is itself a list. Our practice to use a list of characters, i.e., a string:

q)list: enlist "sentinel"
q)type list
0h
q)list ,: `sector
q)list ,: 47
q)count list
3
q)

Note that the use of enlist is essential; without it, list is simply the string:

q)list: ("sentinel")
q)type list
10h
q)count list
8

We use the string "sentinel" because the term sentinel has been used for decades in computer science to denote a value in a data structure that isn't actually part of the data, but rather signals some special condition to the program. It also happens to be a term that doesn't come up often in other domains.

Of course, any code that reads or writes to list needs to understand that the first element is to be ignored. (In our experience, the less code that is aware of that, the less time we spend debugging.) In particular, you must never remove all the data from list; the sentinel must always remain. Otherwise, when you start adding elements again, list's type will become list-of-type-of-the-first-element-added:

q)list: list _/ reverse til count list
q)count list
0
q)type list
0h
q)list ,: `sector
q)type list
11h
q)

This can happen unexpectedly when a mixed-type list is actually a column in a table. See this related faq.

Does q have closures?

Not quite. q supports what it calls projections, which are functions whose arguments are partially specified. Projections can serve the same purpose as closures, albeit (and ironically, we might add) with some additional typing:

f: {[list; n]
{[nn; item]
/ n cannot be referenced here,
/ so we pass it as nn
nn + item}[n; ] each list
}

See: Closure

Why doesn't 'select from tablename where name = `ABC/A' work?

When using symbols that have special characters embedded in them, you need to use a string and cast it to a symbol.

In the example in the question, the / is interpreted as the q adverb over:

q)`ABC/A / interpreted as `ABC over A.
'/

The '/ error means we have misapplied /. Here's how to create the symbol we want:

q)`$ "ABC/A"
`ABC/A
q)select from tablename where name = `$ "ABC/A"

Finally, symbols with embedded spaces are allowed, as long they are not leading or trailing:

q)`$" ABC E "
`ABC E
q)string `$" ABC E "
"ABC E"
q)

What does 'NUC mean?

NUC means, "Non-Upward-Compatible."

How do I save a table to delimited text?

One way, if the format you want is csv, is automatically invoked when using the save function if the name of the destination file ends in .csv:

q)t: ([] x: `a`b; y: 1 2)
q)save `:t.csv
q)\cat t.csv
"x,y"
"a,1"
"b,2"
q)

For other delimiters, you must first format the text using the overload of the 0: function whose first parameter is a character:

q)t: ([] x: `a`b; y: 1 2)
q)"|" 0: t
"x|y"
"a|1"
"b|2"
q)

Notice that, by default, q saves the table column names as a header in the first line of the file. If you want to get rid of the header line, use _ (drop):

q)t: ([] x: `a`b; y: 1 2)
q)1 _ "\t" 0: t
"a\t1"
"b\t2"
q)

Once you have your data as a list of strings complete with delimiters, you use another overload of the 0: function to save the data to disk; this time, the first parameter is the file handle (name) of the destination file:

q)t: ([] x: `a`b; y: 1 2)
q)`:filename.psv 0: 1 _ "|" 0: t
`:filename.psv
q)\cat filename.psv
"a|1"
"b|2"
q)

Since we can't seem to keep all of the overloads for 0: straight (there are more we didn't cover here), we like to wrap the above idiom in a function with a descriptive name. For example,

SaveTableDataAsText: {[path; table; delimiter]
hsym[path] 0: 1 _ delimiter 0: table}

See also: .h.cd

When I launch kdb with a directory, what exactly happens on start up and in what order?

The short answer is, q initializes itself, loads data, then code.

The exact sequence is as follows:

  1. load $QHOME/q.k
  2. load $QINIT/q.q or $QHOME/q.q
  3. load tables contained in /directorypath
  4. load scripts /directorypath/*.q (and *.k or .s) in alphabetical order
Page 1 ... 3 4 5 6 7 ... 12 Next 10 Entries »