A. Built-in Functions
A.0 Overview
The collection of built-in functions in q is rich and powerful. In previous versions of this tutorial we tried for complete coverage of built-ins. However, in this release we no longer attempt to be all-inclusive. First, there are functions that are more advanced than this tutorial. And second, the built-in functions are now well documented on the KX Documentation website; please go there for complete coverage.
In this chapter, we extend the coverage of built-ins in the main text by detailing here those that were omitted or only mentioned in passing in the main text.
Note
- If we do not mention the valence (rank) of a function explicitly, it is unary.
- In the description of each function,
xrefers to the first parameter,yto the second (if it exists) andzto the third (if it exists). - Check the list in 4.0 to see which of the built-ins are multi-threaded (many are as of q4.0).
A.1 and all
The aggregate and is the same as & for people who like typing extra characters.
q)1b and 0b
0b
q)42 and 43
42
The aggregate all is &/, which applies & cumulatively across a numeric list and returns the boolean result. For people who like typing extra characters.
q)all 100100b
0b
q)all 10 20 30
1b
A.2 asc desc
The uniform asc takes a list of comparables x and returns a list sorted in ascending order with the `s# attribute applied. When evaluated on a dictionary, it reorders the key-value pairs (on a copy) so that the values are sorted.
q)asc 3 7 2 8 1 9
`s#1 2 3 7 8 9
q)asc `b`c`a!3 2 1
a| 1
c| 2
b| 3
A table is sorted by the first non-key column and the sorted attribute is set on that column if there is only one non-key column; otherwise the parted attribute is set. The sort is stable in that it preserves the original order of equals; thus it acts as the identity on a sorted list
/ table
q)meta asc ([]a:3 4 1;b:`a`d`s) / sets parted attribute
c| t f a
-| -----
a| j p
b| s
q)meta asc([]a:3 4 1) / sets sorted attribute
c| t f a
-| -----
a| j s
/ keyed table
```q
q)meta asc ([c1:`a`b] c2:2 1; c3:01b) / sets parted attribute
c | t f a
--| -----
c1| s
c2| j p
c3| b
q)meta asc ([c1:`a`b] c2:2 1) / sets sorted attribute
c | t f a
--| -----
c1| s
c2| j s
The uniform desc returns a copy of x, a list of comparables, sorted in descending order. When evaluated on a dictionary, it reorders the key-value pairs so that the values are sorted. The sort is stable in that it preserves the original order of equals; thus it acts as the identity on a sorted list.
q)desc 3 7 2 8 1 9
9 8 7 3 2 1
q)desc `b`c`a!2 3 1
c| 3
b| 2
a| 1
For a table it sorts on the first non-key column and places the `s# attribute on that column.
q)desc([]a:3 4 1;b:`a`d`s)
a b
---
4 d
3 a
1 s
q)meta desc([]a:3 4 1;b:`a`d`s)
c| t f a
-| -----
a| j
b| s
Unlike asc, which sets the parted attribute when there are other non-key columns, desc sets no attribute.
A.3 attr
The function attr returns any attribute of x as a symbol. No attributes is the empty symbol.
| Code | Attribute |
|---|---|
s |
sorted |
u |
unique (hash table) |
p |
partitioned (grouped) |
g |
true index (dynamic attribute): enables constant time update and access for real-time tables |
q)attr til 5
`
q)attr asc 30 20 40 10
`s
A.4 avg avgs mavg
The aggregate avg returns the float arithmetic mean of a numeric or temporal list x.
q)avg 1+til 1000
500.5
The function avg is equivalent to
{sum[x]%count x}
It is possible to apply avg to a nested list provided the sublists conform. In this context, the result conforms to the sublists and the average is calculated recursively on the sublists.
q)avg (1 2;100 200;1000 2000)
367 734f
The uniform avgs is avg\, which computes the running averages of a numeric list.
q)avgs 1+til 10
1 1.5 2 2.5 3 3.5 4 4.5 5 5.5
The binary mavg takes a positive integer x and returns the x-wide moving average of the numeric list y. At each position in y, it computes the average of the x preceding items, or as many as are available up to x.
One way to visualize this is avg uses a moving window of width x extending as far to the left as can fit. It ignores any nulls, which would otherwise null any window that contains them. It is uniform in its second argument.
In the following example, the first item in the result is the average of itself only; the second result item is the average of the first two source items; all other items reflect the average of the item at the position along with its two predecessors.
q)3 mavg 10 20 30 40 50
10 15 20 30 40f
q)3 mavg 0N 10 20 30 40 50
0n 10 15 20 30 40
Tip
For length 1, the result is the source converted to float.
A.5 bin binr
The binary bin takes a simple list of items x sorted in strictly increasing order. It returns the index of the last item in x which is less than or equal to y. It is atomic in y. Loosely speaking, the result of bin is (one less than) the position at which y would fall in x, looking from the left starting at -1. The type of y must strictly match the type of x; no type promotion is performed.
More precisely, the result is -1 if y is less than the first item in x. Otherwise, the result is the index of the last item of x that is less than or equal to y, which is the found index if y is in x. If y is greater than the last item in x, the result is the last index of x.
Note
While the items of x should be in strictly increasing order for the result to meaningful, this condition is not enforced. The result of bin when x is not strictly increasing is essentially undefined.
Tip
For large sorted lists, the binary search performed by bin can be much faster than the linear search performed by (?).
q)L:1.0+til 50000000
q)L bin 25000000.
24999999
q)L?25000000.
2499999
q)\t L bin 25000000.
0
q)\t L?25000000.
22
q)L bin 25000000.5
24999999
q)L?25000000.5
50000000
q)\t L bin 25000000.5
0
q)\t L?25000000.5
20
q)\t L bin 50000000.5
0
q)\t L?50000000.5
115
The binary binr is closely related to bin. Whereas bin looks from the left, binr looks from the right. The result is the index of the first item of the x that is greater than or equal to y.
q)L:1.0+til 50000000
q)L bin 25000000.5
24999999
q)L binr 25000000.5
25000000
A.6 ? Choose
The binary Choose comprises several overloads of ? that generate pseudo-random results. In the case where x is a non-negative long and y is a non-negative numeric value, ? is called Roll and returns a list of pseudo-random numbers with replacement between 0 and y, not including y.
q)5?10
2 4 5 4 2
q)5?10
7 8 5 6 4
q)10?100.0
10.24432 86.71096 72.78528 16.27662 68.84756 81.77547 75.20102 10.868..
q)10?100.0
64.30982 67.08738 67.89082 41.2317 98.77844 38.67353 72.6781 40.46546..
In the case where x is a negative integer and y is a non-negative integer, ? is called Deal and returns a list of pseudo-random numbers without replacement between 0 and y, not including y.
q)-5?10
1 8 5 7 0
q)5?10
2 4 5 4 2
In case y is a list and x is an integer, ? returns a list of x items randomly drawn from y. Again it is called Roll when it acts with replacement for positive x and called Deal when it acts without replacement for negative x.
q)5?`a`b`c`d`e`f
`b`c`f`f`b
q)5?`a`b`c`d`e`f
`e`e`a`e`e
q)-5?`a`b`c`d`e`f
`c`a`d`f`e
q)-5?`a`b`c`d`e`f
`f`a`e`d`c
In case x is a positive integer and y is a symbol of the form `n where n is a positive integer not greater than eight, the result is a random list of x symbols drawn from `a through `p, each comprising exactly n characters. The symbols are distinct when x is negative.
q)10?`1
`c`d`o`m`h`m`n`e`m`m
q)-10?`1
`h`p`j`n`e`o`a`k`l`i
q)-10?`3
`emb`agl`mho`ndm`gmj`egi`gek`hcc`mmb`kbh
The expression -n?n returns a random permutation of til n. This can also be achieved by using 0N as the first parameter to get Permute.
q)0N?10
8 2 4 1 6 0 5 3 7 9
q)0N?`3
`nni`hlc`ikp`egh`mfn`koh`aej`leg`fde`cpg`mih`clp`mea`olm`mpe..
q)0N?("Tom"; "Dick"; "Harry")
"Dick"
"Tom"
"Harry"
A.7 ? Enumerate
The Enum Extend overload of ? enumerates a symbol, with x being the symbolic name of a (presumably unique) list of symbols. It is atomic in y, which is a symbol. The result is the enumeration of y over the domain x. As a side effect, symbols from y not in x are appended to x.
q)sym:`a`b`c
q)`sym?`a`x`b`y`z
`sym$`a`x`b`y`z
q)sym
`a`b`c`x`y`z
Note
The domain can be a file symbol in which case both the file and the variable are updated.
A.8 cor
The binary cor takes two conforming numeric lists and returns the mathematical correlation between the items of the two lists as a float in the range -1f to 1f.
q)23 -11 35 0 cor 42 21 73 39
0.9070229
The function cor is equivalent to
{cov[x;y]%dev[x]*dev y}
A.9 cos acos
The atomic cos is the mathematical cosine of the argument.
q)pi:3.141592653589793
q)cos 0
1f
q)cos pi
-1f
q)cos pi%2
6.123234e-17
The atomic acos is the mathematical inverse of cos. For a float x between -1 and 1, the result is the value between 0 and π whose cosine is x.
q)acos 1
0f
q)acos 1.414213562373095
0n
q)acos -1
3.141593
q)acos 0
1.570796
A.10 count mcount
The aggregate count returns a long representing the number of items in its atom or list parameter. As with any function defined on a lists, it also applies to the value list of a dictionary and hence to tables and keyed tables.
q)count 42
1
q)count til 100
100
q)count `a`b`c`d!10 20 30 40
4
q)count ([] c1:10 20 30; c2:1.1 2.2 3.3)
3
q)count ([k:10 20] c:`one`two)
2
Tip
You cannot use count to determine whether an entity is an atom or list since atoms and singletons both have count 1. Instead test the sign of the type.
q)0>signum type 42
1b
q)0>signum type enlist 42
0b
Tip
Do you know why they call it count? Because it loves to count! Nyah, ha, ha, ha, ha. Vun, and two, and tree, and ...
The binary mcount takes a positive integer x and returns the x-wide moving count of the numeric list y. At each position in y, it counts the number of non-null preceding items up to x. This function is useful in computing other moving quantities, such as moving average, since it correctly reports the effective width of the window at the head of the list and also ignores internal nulls.
q)3 mcount 10 20 30 40 50
1 2 3 3 3i
q)3 mcount 10 20 0N 40 50 60 0N
1 2 2 2 2 3 2i
A.11 cov
The aggregate binary cov takes two conforming numeric lists and returns a float equal to the mathematical covariance between the items of the two lists. Two atoms return 0f.
q)23 -11 35 0 cov 42 21 73 39
411.25
The function cov is equivalent to,
avg[x*y]-avg[x]*avg y
A.12 cross
The binary cross takes atoms or lists as arguments and returns their Cartesian product – that is, the set of all pairs drawn from the two arguments.
q)1 2 cross `a`b`c
1 `a
1 `b
1 `c
2 `a
2 `b
2 `c
Tip
You can also apply cross to dictionaries and tables.
The function cross is equivalent to,
{raze x,\:/:y}
A.13 cut
The binary cut is an instance of Cut that takes a list of integer indices x and a list y. It returns the list obtained by splitting y at the positions in x.
Tip
If the initial item of x is not 0, the first sublist split out is dropped.
q)0 2 5 7 cut 10 20 30 40 50 60 70 80 90 100
10 20
30 40 50
60 70
80 90 1000
q)2 5 7 cut 10 20 30 40 50 60 70 80 90 100
30 40 50
60 70
80 90 100 30 40 50
When x is a strictly positive integral atom, y is split at indices that are multiples of x.
q)2 cut 10 20 30 40 50 60 70 80 90 100
10 20
30 40
50 60
70 80
90 100
q)3 cut 10 20 30 40 50 60 70 80 90 100
10 20 30
40 50 60
70 80 90
,100
A.14 _ Drop, Cut
The binary Cut _ has several forms, depending on the types of its parameters. See also Drop and cut.
Tip
When _ is used infix, surround it with whitespace to avoid it getting mixed up with variable names, since _ is a valid q name character.
When x is an integral atom and y is a list, _ is called Drop and the result is y with x items removed from the head if x is positive and from the tail if x is negative.
q)2 _ 10 20 30 40 50 60 70 80 90 100
30 40 50 60 70 80 90 100
q)-2 _ 10 20 30 40 50 60 70 80 90 100
10 20 30 40 50 60 70 80
When x is a list of integers and y is a list, it is called Cut and returns the list obtained by splitting y at the positions in x. This is the same behavior as cut for this signature.
Tip
If the initial item of x is not 0, the first sublist split out is dropped.
q)0 2 5 7 _ 10 20 30 40 50 60 70 80 90 100
10 20
30 40 50
60 70
80 90 100
q)2 5 7 _ 10 20 30 40 50 60 70 80 90 100
30 40 50
60 70
80 90 100
When y is a dictionary and x is a list of key values whose type matches y, it is called Drop and the result is a dictionary obtained by removing the specified key-value pairs from the target. Since tables and keyed tables are dictionaries, _ applies to them by extension.
q)`a`c _ ([a:10; b:20; c:30])
b| 20
q)`c1`c2 _ ([] c1:`a`b; c2:10 20; c3:1.1 2.2)
c3
---
1.1
2.2
q)([] k:`a`c) _ ([k:`a`b`c] v:10 20 30)
k| v
-| --
b| 20
Tip
The parameter x must be a list, so a single value for the first parameter in this form must be enlisted.
q)(enlist `b) _ ([a:10; b:20; c:30])
a| 10
c| 30
When x is a list or a dictionary and y is an atom representing an index or key, it is called Drop and the result is obtained by deleting the specified item from (a copy of) x.
q)01 102 103 104 105 _ 2
1 102 104 105
q)([a:10; b:20; c:30]) _ `b
a| 10
c| 30
^
q)([k:101 102 103] c:`one`two`three) _ 102
k | c
---| -----
101| one
103| three
Note
The last overload cannot accept a list of indices to be dropped. Why?
A.15 deltas
The uniform deltas is -':, which returns the difference of each item in a numeric list with its predecessor.
q)deltas 1 2 3 4 5
1 1 1 1 1
q)deltas 96.25 93.25 58.25 73.25 89.50 84.00 84.25
96.25 -3 -35 15 16.25 -5.5 0.25
Tip
If you are looking to bound the absolute difference between successive elements, the second example shows that the initial item of the result will be troublesome.In this case, you can use,
deltas0:{first[x] -': x}
In our example above,
q)deltas0 96.25 93.25 58.25 73.25 89.50 84.00 84.25
0 -3 -35 15 16.25 -5.5 0.25
A.16 dev mdev
The aggregate dev returns the float standard deviation of a numeric list – the square root of the variance.
q)dev 1000?100.
29.40271
The function (dev) is equivalent to,
{sqrt var x}
The binary mdev takes a positive integer x and returns the x-wide moving standard deviation of the numeric list y. At each position in y, it computes the standard deviation of the x preceding items, or as many as are available in the moving window up to that position. It excludes internal nulls from the calculation.
q)3 mdev 10 20 30 40 50
0 5 8.164966 8.164966 8.164966
q)3 mdev 10 20 30 0N 50
0 5 8.164966 5 10
A.17 differ
The uniform differ is
"b"$ not (~':)
It asks if each item in a list is not identical to its predecessor. The item at index 0 in the result is always 1b.
q)differ 0 1 1 2 3 2 2 2 4 1 1 3 4 4 4 4 5
11011100110110001b
q)differ "mississippi"
11101101101b
q)differ (1 2; 1 2; 3 4 5)
101b
One use of differ is to locate runs of repeated items in a list.
q)L:0 1 1 2 3 2 2 2 4 1 1 3 4 4 4 4 5
q)nd|next nd:not differ L
01100111011011110b
A.18 distinct
The unary distinct returns the unique items in its list argument in order of first occurrence. Note that it does not apply the `u# attribute. (The Q Gods explain that this would incur the overhead of creating a hash table which you likely don't want for a garden variety call to distinct.
q)distinct 1 2 3 2 3 4 6 4 3 5 6
1 2 3 4 6 5
Following is a test for existence of duplicates.
{count[x]=count distinct x}
Since a table is a list of records, distinct effectively removes duplicate rows. All fields' records must be identical for
them to be considered identical.
q)distinct ([]a:1 2 3 2 1;
b:`washington`adams`jefferson`adams`washington)
a b
------------
1 washington
2 adams
3 jefferson
q)distinct ([]a:1 2 3 2 1;
b:`washington`adams`jefferson`adams`wasington)
a b
------------
1 washington
2 adams
3 jefferson
1 wasington
A.19 enlist
The multivalent enlist returns a list whose items comprise its arguments. The most common use is to create a singleton list from an atom. Unlike user-defined functions, the number of arguments to enlist is not restricted to eight.
Important
To save space, the display of an enlisted item uses , which is the k form of enlist.
q)enlist 42
,42
q)count enlist 10 20 30
1
q)enlist[1;2;3;4;5;6;7;8;9;10]
1 2 3 4 5 6 7 8 9 10
/ a list with one column dictionary *is* a table
q)enlist ([c1:`a; c2:100])
c1 c2
------
a 100
Tip
Since amend in place does not require its target to be previously defined, here is a hack to create and assign a singleton atom.
q)x,:42
q)x~enlist 42
1b
A.20 eval and reval
Both eval and reval evaluate a list representing a valid q parse tree; the same code is used in the q interpreter. Such a list can be produced using parse on a string containing a valid q expression, or by hand – if you know what you're doing. A full discussion of parse trees is beyond the scope of this tutorial.
q)parse "a:6*7"
:
`a
(*;6;7)
q)eval parse "a:6*7"
42
q)a
42
/ create parse tree by hand
q)eval (+;1;(*;6;7))
43
The reval function is the same as eval except that it bocks any and all behavior that could be potentially destructive. Specifically it behaves as if command-line options -u 1 and -b were active; it also blocks all system calls which change state. See the documentation on the KX Documentation website for details.
A.21 except
The binary except takes a list (or dictionary) x and an atom or list y that is of the same type as x and returns the items in x that are not in y. Otherwise put, it excludes the items of y from x. The returned items are in the order of their first occurrence in x.
q)1 2 3 4 3 2 except 2
1 3 4 3
q)string[2025.01.01] except "."
"20250101"
q)([a:10; b:20; c:30; d:40]) except ([a:10; d:40])
20 30
q)([] c1:`a`b`c`d; c2:10 20 30 40) except ([] c1:`a`d; c2:10
40)
c1 c2
-----
b 20
c 30
Tip
The result of (except) is always a list.
A.22 exit
Use exit with a integer parameter to terminate the q process immediately, returning the parameter to the OS. It is blocked
during (reval) or with -u on the command line.
Important
There is no prompt for confirmation.
A.23 ^ fill and Fills
The binary fill ^ takes an atom x and a list y. It returns (a copy of) y having null values replaced with x.
q)42^1 2 3 0N 5 0N
1 2 3 42 5 42
q)"_"^"Now is the time"
"Now_is_the_time"
q)`NA^`First`Second``Fourth
`First`Second`NA`Fourth
Fill is atomic in the second parameter.
q)42^(1;0N;(100;200 0N))
1
42
(100;200 42)
Like all functions, fill operates on the values of a dictionary.
q)42^([a:100; b:0N; c:200; d:0])
a| 100
b| 42
c| 200
d| 0
q)0^([]c1:1.0 2.0 0n; c2:0N 2 0N)
c1 c2
-----
1 0
2 2
0 0
The uniform fills is ^\, which fills forward, meaning that null items are replaced with preceding non-nulls.
q)fills 1 0N 3 0N 0N 5
1 1 3 3 3 5
q)fills `x``y```z
`x`x`y`y`y`z
q)update fills c2 from ([] `a`b`c`d`e`f; c2:1 0N 3 0N 0N 5)
x c2
----
a 1
b 1
c 3
d 3
e 3
f 5
Tip
If you need to fill initial nulls, use the corresponding binary form of ^\.
q)fills 0N 0N 3 0N 5
0N 0N 3 3 5
q)0 ^\ 0N 0N 3 0N 5
0 0 3 3 5
A.24 ? Find
This binary overload of ? called Find takes a list x and an atom y of the same type as x. It returns the index of the first occurrence of y in x or the count of x if it is not found. It is atomic in y.
Zen Moment
Viewing a list or dictionary as a mapping, find is the (partial) inverse mapping.
The simplest case is when y is an atom.
q)100 99 98 87 96 98?98
2
q)`one`two`three?`four
3
q)"Now is the time"?"the" / strings are just lists of char
7 8 9
Tip
The first example demonstrates that Find returns only the index of the first occurrence of y.
To find the indices of all occurrences you could use,
q){where x=y}[100 99 98 87 96 98;98]
2 5
Find also works on general lists as long as they conform, although if you need this you should probably consider redesigning your program.
q)(1 2; 3 4; `a`b)?`a`b
2
q)((0;1 2);3 4;5 6)?5 6 / uh oh
2
Find can also take a dictionary as x and a dictionary value as y. It returns the first key that maps to value. It is atomic in y.
q)([a:10;b:20;c:30;d:40])?10
`a
q)([a:10;b:20;c:30;d:40])?10 30
`a`c
By extension, Find applies to tables and keyed tables.
q)([] c1:`a`b`c; c2:10 20 30)?([c1:`b;c2:20])
1
q)([] c1:`a`b`c; c2:10 20 30)?(`b;20)
1
q)([k:1 2 3] c:100 101 102)?101
k| 2
A.25 flip
Use flip to transpose a rectangular list, column dictionary or table.
When x is a rectangular list, the items are rearranged, effectively reversing the first two indices in indexing. For example,
q)show m:(1 2 3;10 20 30)
1 2 3
10 20 30
q)flip m
1 10
2 20
3 30
When flip converts a column dictionary to a table and vice versa, no data is actually rearranged. Only column indexing is reversed.
q)d:([c1:`a`b`c; c2:10 20 30])
q)t:([] c1:`a`b`c; c2:10 20 30)
q)d[`c1;2]~t[2;`c1]
1b
A.26 getenv setenv
Use getenv with a symbol naming an OS environment variable to return the value (if any) of that environment variable as a string.
q)getenv `SHELL
"/bin/zsh"
The binary setenv takes x a symbol name of an OS environment variable and a string y. It calls the underlying OS to set the
environment variable named in x to the specified y.
q) `FOO setenv "test"
q)getenv `FOO
"test"
A.27 group
Apply group to a list x to return a dictionary in which each distinct item in x is mapped to the indices of its occurrences in x. The keys of the result are in the order of their first appearance in
x.
q)group "i miss mississippi"
i| 0 3 8 11 14 17
| 1 6
m| 2 7
s| 4 5 9 10 12 13
p| 15
q)count each group "i miss mississippi"
i| 6
| 2
m| 2
s| 6
p| 2
A.28 gtime ltime
The atomic gtime converts local time to UTC time.
q).z.P
2025.07.12D08:18:10.378409000
q)gtime .z.P
2025.07.12D12:18:14.878884000
The atomic ltime converts UTC time to local time.
q).z.P
2025.08.25D15:36:26.432993000
q)ltime .z.p
2025.08.25D15:36:35.511399000
q).z.p
2025.08.26D01:36:40.355924000
A.29 iasc idesc Grade
The uniform iasc takes a list or a dictionary. The result is a list of the indices/keys of x in the order needed to sort it. Otherwise put, composing x with the result of iasc sorts in ascending order.
q)L:30 70 20 80 10 90
q)show I:iasc L
4 2 0 1 3 5
q)show S:L I
10 20 30 70 80 90
q)L~S iasc I
1b
q)d:([c:30;a:10;b:20])
q)iasc d
`a`b`c
q)d iasc d
10 20 30
q)(iasc d)#d
a| 10
b| 20
c| 30
This is useful when you want to use one list to control the order of others – e.g., manual sort on the serialized columns of a splayed table (see 14.2).
Zen Moment
The composite iasc iasc provides the list of indices that transforms the sorted entity back to the original.
The uniform idesc takes a list or a dictionary. The result of idesc is a list of the indices/keys of x in the order needed to sort its argument. Otherwise put, composing x with the result of idesc sorts in descending order.
q)L:30 70 20 80 10 90
q)show I:idesc L
5 3 1 0 2 4
q)show S:L I
90 80 70 30 20 10
q)S iasc I
30 70 20 80 10 90
q)idesc d
`c`b`a
q)d idesc d
30 20 10
q)(idesc d)#d
c| 30
b| 20
a| 10
This is useful when you want to use one list to control the order of others – e.g., manual sort on the serialized columns of a splayed table (see 14.2).
Zen Moment
The composite iasc idesc provides the list of indices that transforms the sorted entity back to the original.
A.30 identity
The unary :: is the identity function – i.e., it returns its argument.
q)::[42]
42
q)(::) `Zaphod
`Zaphod
Tip
The identity function cannot be used naked with juxtaposition or @. You must either enclose it in parentheses or
enclose its argument in square brackets. This is to disambiguate this use from others.
A.31 in
The binary function in is atomic in x and takes an atom or list y. It returns a boolean indicating whether source appears in target. The comparison is strict with regard to type. When x is a list and y is a list of lists of the same type as x, it treats the lists of y as irreducible for the comparison.
q)42 in 0 6 7 42 98
1b
q)4 in 42
0b
q)"4" in "42"
1b
q)"cat" in "abcdefg"
110b
q)"cat" in ("dog"; "cat"; "parrot")
1b
A.32 inter union
The binary inter returns the items in x that occur in y.
q)1 2 3 4 inter 3 4 4 5
3 4
Note
Lists differ from sets in that they are ordered and allow
duplicates. So inter is not the list equivalent of set
intersection, despite of what the KX web site says. You can obtain this
with distinct.
q)1 2 3 1 4 inter 4 1 4
1 1 4
q)distinct 1 2 3 1 4 inter 4 1 4
1 4
Tip
You can use inter to find common records in tables having
identical schemas.
q)([] c1:`a`b`c; c2:10 20 30) inter ([] c1:`c`d; c2:30 40)
c1 c2
-----
c 30
The binary union returns the list equivalent of the set theoretic
union of its two list parameters. The result has the distinct items of
x,y in order of their first appearance.
q)1 1 2 3 union 2 2 3 4
1 2 3 4
q)"a good time" union "was had by all"
"a godtimewshbyl"
Since a table is a list of records, union can be used to perform the
analogue of SQL UNION for tables having the same schemas. Observe that
this is different from join , since duplicate records are eliminated.
q)([] c1:`a`b`c; c2:10 20 30) union ([] c1:`b`c`d; c2:20 300 400)
c1 c2
------
a 10
b 20
c 30
c 300
d 400
Tip
Use uj for tables that do not have matching schemas – see
9.9.7.
A.33 inv
Use inv to return the inverse of a float matrix. An integer matrix
must be cast to float.
q)inv (1.1 2.1 3.1; 2.3 3.4 4.5; 5.6 7.8 9.8)
-8.165138 16.51376 -5
12.20183 -30.18349 10
-5.045872 14.58716 -5
Note
Since q3.6 inv uses LU (lower-upper) decomposition.
A.34 , Join
The binary Join , appends y to x. When both operands are either
lists or atoms, the result concatenates y to x.
q)1,2
1 2
q)1 2 3,4
1 2 3 4
q)1 2,3 4
1 2 3 4
The result is a general list unless all items are of homogeneous type.
q)1 2 3,4.0
1
2
3
4f
When both x and y are dictionaries, the result is the merge of the
y into x using upsert semantics. Otherwise put, assignments in the
second parameter prevail over those in the first.
q)([a:10;b:20;c:30]),([c:300;d:400])
a| 10
b| 20
c| 300
d| 400
By extension, you can use , on tables and keyed tables with identical
schemas where it is analogous to a union join in SQL.
q)([] c1:`a`b;c2:10 20),([]c1:1#`s; c2:30)
c1 c2
-----
a 10
b 20
s 30
Important
You can use ,: to append to a list in place,
meaning no copy is made. This also has the advantage that the variable
being assigned does not have to be defined before first use. In a fresh
q session,
q)x
'x
[0] x
^
q)x,:42
q)x,:100 200 300
(,:) does not allow mixing types unless the list is
already a general list.
A.35 key
The key operator vies for the title of most overloaded q operator. Its
eponymous action is to return the key of a dictionary, including the
special case of the key portion of a keyed table. It can be applied by
value or name.
q)key ([a:10;b:20;c:30])
`a`b`c
q)key kt:([k:`a`b`c] v:10 20 30)
k
-
a
b
c
q)key `kt
_
A context – i.e. the content of a namespace – is a dictionary, so key
applied to the symbolic name will return the names of its constituents.
Observe that contexts below the root all have an initial null symbol. In
a fresh q session,
q)key `.
`symbol$()
q)a:42
q)key `.
,`a
q).jab.a:42
q)key `.jab
``a
key to the null symbol.
q)key `
`q`Q`h`j`o`jabkey
You can use key to determine if a variable exists in the current
namespace.
q)x
'x
q)()~key `x / tests if x exists in current namespace
1b
q)x:42
q)key `x
`x
Given a simple list, key returns the symbolic name of its type.
q)key 10 20 30
`long
q)key "so long"
`char
Given an enumerated entity, key returns the name of its enumeration
domain. This applies to foreign key columns, where it returns the name
of the target keyed table.
q)key `sym?`a`b`a`c`a
`sym
q)key `sym1?`a`b`a`c`a
`sym1_
q)kt:([k:`a`b`c] v:10 20 30)
q)t:([] k:`kt$`a`b`a`b`a; v: 10 20 30 49 59)
q)key t[`k]
`kt
Given an I/O handle corresponding to a directory, key returns a list
of the symbolic names of entities in that directory, including hidden
files.
q)\ls q
"k4.lic"
"kc.lic.old"
"m64"
"q.k"
"sp.q"
q)key `:q
`s#`.DS_Store`k4.lic`kc.lic.old`m64`q.k`sp.q
Tip
An empty directory returns an empty list of symbols whereas a non-existent directory returns an empty general list. This provides a simple test for the existence of a directory.
q)\ls Q4M/jab
ls: Q4M/jab: No such file or directory
q)()~key `:Q4M/jab
1b
q)\mkdir Q4M/jab
q)key `:Q4M/jab
`s#`symbol$()
Given an I/O handle corresponding to a file, key returns the symbolic
file name if the file exists and the general empty list () if it does
not. As above, this provides a test for existence of the file.
q)`:Q4M/trade.q 0: enlist "dummy"
`:Q4M/trade.q
q)key `:Q4M/trade.q
`:Q4M/trade.q
q)()~key `:Q4M/quote.q
1b
Last, but not least, key also acts as a synonym of til.
q)key 10
0 1 2 3 4 5 6 7 8 9
A.36 like
The binary like performs matching of a string (or symbol) x
according to the pattern in the string (or symbol) y. It returns a
boolean result indicating whether y is matched. The pattern is expressed as a mix of regular characters and special
formatting characters.
The special chars are ?, *, the pair [ and ], and finally ^ that is enclosed in square
brackets. The special char ? represents an arbitrary single character in the pattern.
q)"fan" like "f?n"
1b
q)"fun" like "f?n"
1b
q)"foP" like "f?p"
0b
The special char * represents an arbitrary sequence of characters
in the pattern.
Note
As of this writing (July 2025), only a single occurrence of
* is allowed in the pattern, except that a * can occur at both
the beginning and end of the pattern.
q)"how" like "h*"
1b
q)"hercules" like "h*"
1b
q)"wealth" like "*h"
1b
q)"flight" like "*h*"
1b
q)"Jones" like "J?ne*"
1b
q)"Joynes" like "J*ne*"
'nyi
The special character pair [ and ] encloses a sequence of
alternatives for a single character match.
q)"flap" like "fl[ao]p"
1b
q)"flip" like "fl[ao]p"
0b
q)"459-0609" like "[0-9][0-9][0-9]-0[0-9][0-9][0-9]"
1b
q)"459-0609" like "[0-9][0-9][0-9]-1[0-9][0-9][0-9]"
0b
The special character ^ is used in conjunction with [ and
] to indicate that the enclosed sequence of characters is
disallowed. For example, to test whether a string ends in a non-numeric
character,
q)"M26d" like "*[^0-9]"
1b
q)"Joe999" like "*[^0-9]"
0b
Enclose a special char in square brackets to escape it as a normal char.
q)"a_c" like "a*"
1b
q)"a_c" like "a[*]"
0b
q)"a*c" like "a[*]c"
1b
As usual with dictionaries, like matches on the values.
q)([a:`nuba;b:`devi;c:`lorenzo]) like "devi"
a| 0
b| 1
c| 0
A.37 lower upper
The atomic lower takes a char, string or symbol x and returns the
result of converting all alpha characters in x to lower case.
q)lower `A
`a
q)lower "a Bc42De?"
"a bc42de?"
The atomic (upper) takes a char, string or symbol x and returns the
result of converting any alpha characters to upper case.
q)upper `a
`A
q)upper `a`b
`A`B
q)upper "a Bc42De"
"A BC42DE"
Note
Only letters in the ASCII range are affected.
q)-1 upper "árvíztűrő"
áRVíZTűRő
A.38 lsq
The binary matrix operator lsq takes float matrix parameters A and B
and returns the matrix X that solves the following matrix equation,
where · is matrix multiplication.
A = X·B
For example,
q)A:(1.1 2.2 3.3;4.4 5.5 6.6;7.7 8.8 9.9)
q)B:(1.1 2.1 3.1; 2.3 3.4 4.5; 5.6 7.8 9.8)
q)A lsq B
1.211009 -0.1009174 2.993439e-12
-2.119266 2.926606 -3.996803e-12
-5.449541 5.954128 -1.758593e-11
We note that lsq solves a normal equations matrix via Cholesky
decomposition – solving systems is more robust than matrix inversion and
multiplication. Thus although lsq is theoretically equivalent to
computing the inverse explicitly, the results do not agree within
multiplicative tolerance due to different methods used.
q)A mmu inv B
1.211009 -0.1009174 7.105427e-15
-2.119266 2.926606 0
-5.449541 5.954128 7.105427e-15
q)(A lsq B)=A mmu inv B
000b
000b
000b
A.39 max maxs mmax
The aggregate max is |/, which applies | cumulatively across a
list of items of underlying numeric type and returns the final result.
It is the same as (any) on a boolean list. Nulls are ignored, except
that if all the items of x are null, the result is negative infinity.
q)max 100100b
1b
q)max 10?2025.01.01
2017.09.06
The uniform maxs is |\, which applies | across a list of
comparable items and returns the intermediate results. Nulls are
ignored, except that if all the items of x are null, the result is
negative infinity.
q)maxs 1 2 5 4 10
1 2 5 5 10
q)maxs "Beeblebrox"
"Beeelllrrx"
The binary mmax takes a positive integer x and returns the x-wide
moving maximum of the numeric list y. At each position in y, it
computes the maximum of the x preceding items, or as many as are
available in the moving window up to that position. It excludes internal
nulls from the calculation.
q)3 mmax 20 10 30 50 40
20 20 30 50 50
q)3 mmax 20 10 30 0N 40
20 20 30 30 40
A.40 md5
The unary function md5 computes the MD5 (Message Digest Algorithm 5)
hash of a string as a list of 16 bytes.
q)md5 "Life the Universe and Everything"
0x0e9a5631e4db880d43808504d05348df
From the KX Documentation website: MD5 is a widely used, Internet standard (RFC 1321), hash function that computes a 128-bit hash, commonly used to check the integrity of files. It is not recommended for serious cryptographic protection, for which strong hashes should be used.
A.41 med
The aggregate med returns the float median of a numeric list.
q)med 1000?1000.
509.5941
q)med 1000000?1000000
The function med is equivalent to,
{avg x (iasc x)@floor .5*-1 0+count x,:()}
A.42 min mins mmin
The aggregate min is &/, which applies & cumulatively across a
list of underlying numeric type and returns the final result. It is the
same as and for a boolean list. Nulls are ignored, except that if the
argument has only nulls, the result is infinity. The minimum of an atom
is itself.
q)min 100?100
1
q)min 100100b
0b
The uniform mins is &\, which computes the cumulative minimums of a
list of comparables and returns the intermediate results. Nulls are
ignored, except that if the argument has all nulls, the result is
infinity.
q)mins 10 4 0N 1 2
10 4 4 1 1
q)mins "the cat"
"theecaa"
The binary mmin takes a positive integer x and returns the x-wide
moving minimum of the numeric list y. At each position in y, it
computes the minimum of the x preceding items, or as many as are
available in the moving window up to that position. It excludes internal
nulls from the calculation.
q)3 mmin 20 10 30 50 40
20 10 10 10 30
A.43 $ mmu matrix multiply
The binary matrix multiplication mmu returns the matrix product of its
two float vector or matrix parameters, which must be of the correct
shapes. It reduces to dot product on vectors. Integer matrices must be
cast to float.
q)m1:(1.1 2.2 3.3;4.4 5.5 6.6;7.7 8.8 9.9)
q)m1 mmu flip m1
16.94 38.72 60.5
38.72 93.17 147.62
60.5 147.62 234.74
q)m2:`float$(0 0 1; 0 1 0; 1 0 0)
q)m2 mmu m2
1 0 0
0 1 0
0 0 1
q)1 2 3f mmu 1 2 3f
14f
Note
The $ operator is overloaded to yield matrix multiplication when its parameters are float vectors or matrices.
q)m2 $ m2
1 0 0
0 1 0
0 0 1
A.44 next prev xprev
The uniform next returns its list x shifted one position to the left
with a null (or empty list for nested lists) in the last item. Otherwise
put, each item in x is replaced with its successor.
q)next 1 2 3 4 5
2 3 4 5 0N
q)next (1 2; 3 4 5; 6 7)
3 4 5
6 7
`long$()
The uniform prev returns a list x shifted one position to the right
with a null (or empty list in the case of a nested list) in the first
item. Otherwise put, each item in x is replaced with its predecessor.
q)prev 1 2 3 4 5
0N 1 2 3 4
q)prev (1 2; 3 4 5; 6 7)
`long$()
1 2
3 4 5
The binary xprev takes an integer x and shifts the list y by x
positions. When x is 0 or positive, the shift is forward; otherwise it
is backward. The beginning – respectively end – of the list is filled
with x null items (or empty list items for nested y).
q)2 xprev 10 20 30 40 50
0N 0N 10 20 30
q)-2 xprev 10 20 30 40 50
30 40 50 0N 0N
q)
q)2 xprev (1 2 3; 4 5; enlist 6; 7 8)
`long$()
`long$()
1 2 3
4 5
3
4 5
A.45 null
The atomic function null tests its argument for null value. It is
preferred to testing for equality as it works for all types.
q)null 42
0b
q)null 0n
1b
q)null "Now is the time"
000100100010000b
q)null (1; 3 0N; ((5; 0N); 7))
0b
01b
(01b;0b)
q)
A common idiom combines where with null to obtain the positions of
the null items in a list.
q)where null 1 2 3 0N 5 0N
3 5
Because null is atomic, it picks out null values in all fields of a
table.
q)null ([] c1:`a``b; c2:0N 20 30)
c1 c2
-----
0 1
1 0
0 0
This can be used to identify null columns.
q)where all null ([] c1:`a`b`c; c2:0n 0n 0n; c3:10 0N 30)
,`c2
A.46 or any
The binary or is the same as | for people who like typing extra
characters.
q)1b or 0b
1b
q)42 or 43
43
The aggregate any is |/, which applies | cumulatively across a
numeric list and returns the boolean result. For people who like typing
extra characters.
q)any 100100b
1b
q)any null til 10
0
A.47 over scan
The higher-order function over is a convenience function that renames
the unary form of / for people who like typing extra characters.
Note
Symbolic operands must be parenthesized.
q){x+2*y} over 2 3 5 7
32
q)
q)(+) over 2 3 5 7
17
The higher-order function scan is a convenience function that renames
the unary form of \ for those who like to type more characters.
Note
Symbolic operators must be parenthesized.
q){x+2*y} scan 2 3 5 7
2 8 18 32
q)(+) scan 2 3 5 7
2 5 10 17
A.48 parse
Use parse to produce a q parse tree from a string representing a q
expression. Applying eval to the result of parse effectively
evaluates the expression. The composition of eval after parse is
essentially the q interpreter. A discussion of q parse trees is beyond
the scope of this tutorial.
q)parse "7*4+2"
*
7
(+;4;2)
q)eval parse "7*4+2"
42
Note
It is useful to apply parse to a string containing a query
template for the purpose of expressing the query in functional form. The
result will often include k code but it is usually recognizable and you
can use it in functional form. The constraint portion of the resulting
parse tree will contain an extra level of nesting displayed in the k
form ,,. You must remove one level for the functional form.
q)t:([]c1:`a`b`c; c2:10 20 30)
q)parse "select c2:2*c2 from t where c1=`c"
?
`t
,,(=;`c1;,`c)
0b
(,`c2)!,(*;2;`c2)
q)?[`t; enlist (=;`c1;enlist `c); 0b; (enlist `c2)!enlist (*;2;`c2)]
c2
--
60
A.49 peach
A full discussion of how q handles concurrency and distributed processing is beyond the scope of this text. We provide a description of the essential features as of this writing (July 2025) and refer the reader to "Parallel processing" on the KX Documentation website for up-to-date details.
Concurrency in q uses two basic constructs: peach and secondary
threads (secondaries). The maximum number of secondaries are declared
to the q process at startup and the actual number can be set at runtime
from the console with \s. The function peach is a "parallel"
version of each that applies a function over a list by distributing
the items of the list across secondaries.
While each and peach perform the same computation and return the
same result, their performance can be drastically different. If q is not
started with secondaries, peach reverts to each, meaning function
application across a list occurs sequentially in the main q thread.
Note
For those who are not symbolically challenged, for a unary
function f, we point out that f each is actually f' and f peach
is actually f':.
A.49.1 Threads
When q is started with -s n, the q process automatically spawns n
secondary threads in addition to the main thread. When you subsequently
use (peach) to apply a function – i.e., map it across a list – the
application is automatically distributed across the secondary threads
for you.
The result of the application is the same as if you had used
(each) but if q is running on a machine with multiple cores, you should
expect a speedup, depending on what the function does, how secondary
threads are allocated to cores and the load on your machine.
For example, on the author's laptop that has 10 cores, we find
that the benefit of multiple secondaries for evaluating a
compute-intensive calculation on a list of 8 items plateaus at 8
secondaries.
jaborror@unalome ~ % q
q)\t {sum exp x?1.0} each 8#1000000
51
q)\t {sum exp x?1.0} peach 8#1000000
51
jaborror@unalome ~ % q -s 2
q)\t {sum exp x?1.0} each 8#1000000
42
q)\t {sum exp x?1.0} peach 8#1000000
27
jaborror@unalome ~ % q -s 4
q)\t {sum exp x?1.0} each 8#1000000
31
q)\t {sum exp x?1.0} peach 8#1000000
16
jaborror@unalome ~ % q -s 8
q)\t {sum exp x?1.0} each 8#1000000
28
q)\t {sum exp x?1.0} peach 8#1000000
9
jaborror@unalome ~ % q -s 10
q)\t {sum exp x?1.0} each 8#1000000
29
q)\t {sum exp x?1.0} peach 8#1000000
9
In order to maintain consistency during concurrent application, the following restriction is placed on function evaluation within secondary threads.
Code executed in a secondary thread cannot update global variables – i.e., a function can only update local variables.
Warning
If you use a timer on the main thread or other tricks to update globals that are read by secondary threads, you are cruising for a bruising. While these updates are locked, there is no notion of a transaction with attendant rollback. It is unlikely that your function executing on the timer is atomic at the hardware level. Should it fail mid-flight, you should expect the workspace would be in an inconsistent state with no built-in recovery mechanism.
A.49.2 Workload distribution
From the KX Documentation website: In q4.1t 2024.01.04,
peachWorkload Distribution methodology changed to dynamically redistribute workload and allow nested invocation. The limitations on nesting have been removed, sopeach(and multi-threaded primitives) can be used insidepeach. To facilitate this, round-robin scheduling has been removed. Even though the initial work is still distributed in the same manner as before for compatibility, the workload is dynamically redistributed if a thread finishes its share before the others.
See the KX Documentation website or the latest documentation on peach processing.
A.50 prd prds
The aggregate prd is */, which applies * cumulatively across a
numeric list and returns the final result.
Tip
Note the missing o in the name.
q)prd 1+til 5
120
q)prd 1+til 5
120
q)prd 10?100.
5.677673e+16
It is possible to apply prd to a nested list provided the sublists
conform. In this case, the result conforms to the sublists and the
product is calculated recursively on the sublists.
q)prd (1 2; 100 200; 1000 2000)
Z100000 800000
The uniform prds is *\, which applies * cumulatively across a
list of numeric type and returns the intermediate results.
Tip
Note the missing o in the name.
q)prds 1+til 5
1 2 6 24 120
A.51 prior
The function prior is a convenience function that renames the unary
form of ': for people who like typing extra characters.
Tip
You likely still won't be happy with the initial item of the result.
q)(-) prior 10 11 12 13 14
10 1 1 1 1
A.52 rank
The uniform rank returns the sort order of each item in a list of
comparables.
q)rank 50 20 30 10 40
4 1 2 0 3
q)iasc iasc 50 20 30 10 40
4 1 2 0 3
q)rank `x`a`b`z`c
3 0 1 4 2
A.53 ratios
The uniform ratios is %':, which applies % across a list of
numeric type and returns the intermediate results. That is, it returns
the ratio of each item with its predecessor.
q)ratios 10 20 30 40 50
10 2 1.5 1.333333 1.25
Tip
The initial item in the result is not 1.0. If you are
looking to bound the relative difference between successive elements,
this example shows that the initial item of the result will be
troublesome.
In this case, you can use,
ratios1:{first[x] %': x}
For our example above,
)ratios1:{first[x] %': x}
q)ratios1 10 20 30 40 50
1 2 1.5 1.333333 1.25
A.54 raze
The unary raze is ,/. It effectively eliminates the top-most level
of nesting from a list by joining – i.e., concatenating – across it.
q)raze (1 2 3;3; 4 5)
1 2 3 3 4 5
Observe that raze only removes the top-most level of nesting but you
can use each repeatedly to reach deeper levels. Also you can flatten
the entire structure of a nested list with the iterated raze/. (This
is a good q test question).
q)raze ((1 2;3 4);(5;(6 7;8 9)))
1 2
3 4
5
(6 7;8 9)
q)raze each ((1 2;3 4);(5;(6 7;8 9)))
1 2 3 4
(5;6 7;8 9)
q)(raze each) each ((1 2;3 4);(5;(6 7;8 9)))
1 2 3 4
,5 6 7 8 9
q)raze/[((1 2;3 4);(5;(6 7;8 9)))]
1 2 3 4 5 6 7 8 9
A.55 reverse
The uniform function reverse inverts the item order of its argument.
q)reverse 1 2 3 4 5
5 4 3 2 1
q)reverse ([a:10; b:20; c:30])
c| 30
b| 20
a| 10
q)reverse ([] c1:`a`b`c; c2:10 20 30)
c1 c2
-----
c 30
b 20
a 10
q)reverse ([k:`a`b`c] v:10 20 30)
k| v
-| --
c| 30
b| 20
a| 10
For nested entities, the reversal takes place only at the topmost level but you can use (each) to reach lower levels.
q)reverse (1 2 3;"abc";`Four`Score`and`Seven)
`Four`Score`and`Seven
"abc"
1 2 3
q)reverse each (1 2 3;"abc";`Four`Score`and`Seven)
3 2 1
"cba"
`Seven`and`Score`Four
A.56 rotate
The uniform binary rotate takes an integer x and returns the result
of rotating y by x positions. The rotation is to the left for
positive x and to the right for negative x. When x is 0, it
returns y.
q)2 rotate 1 2 3 4 5
3 4 5 1 2
q)22 rotate 1 2 3 4 5
3 4 5 1 2
A.57 rsave rload
The convenience function rsave takes a symbolic directory handle and
splays to it a table from a variable with the same name as the
directory. The preferred way to do this is with set, which allows the
directory name to be specified.
Note
Do not include the trailing / in the directory handle.
q)t:([] c1:10 20 30; c2:1.2 2.2 3.3)
q)rsave `:db/t
`:db/t/
q)`:db/t1/ set t
`:db/t1/
The convenience function rload takes a symbolic directory handle and
loads a splayed table into a variable with the same name as the splayed
directory. The usual way to do this is with get, whose result can be
assigned to an arbitrary variable.
Note
Do not include the trailing / in the directory handle.
q)`:db/t/ set ([] c1:10 20 30; c2:1.2 2.2 3.3)
`:db/t/
q)rload `:db/t
`t
q)count t
3
q)t1:get `:db/t
q)count t1
3
A.58 scov
The binary scov returns the statistical covariance of two conforming
numeric lists.
q)2 3 5 7 scov 4 3 0 2
-2.416667
It is equivalent to:
{cov[x;y]*count[x]%-1+count x}
A.59 sdev
The aggregate sdev returns the statistical standard deviation of its
numeric list argument.
q)sdev 10 343 232 55
155.1322
It is equivalent to:
{sqrt var[x]*count[x]%-1+count x}
A.60 sin asin
The atomic sin takes a float and returns its mathematical sine.
q)pi:3.141592653589793
q)sin pi
1.224647e-16
q)sin pi%2
1f
The atomic asin is the mathematical inverse of sin. For a float x
between -1 and 1, asin returns the float between -π/2 and π/2 whose
sine is x.
q)asin 0
0f
q)asin 1.414213562373095%2
0.7853982
q)asin 1
1.570796
q)asin -1
-1.570796
A.61 ss ssr
The binary ss, for "string search", performs similar pattern
matching as like against the string x, looking for matches with y.
The result is a list containing the position(s) of the matches of y in
x.
q)ss["Now is the time for all good men to come to";"me"]
13 29 38
q)"fun" ss "f?n"
,0
If no matches are found, an empty list of long is returned.
q)ss["ab";"z"]
`long$()
Note
You cannot use * to match with ss.
The ternary ssr, for "string search and replace", extends the
capability of ss with replacement. The result is a string based on the
string x in which all matches of the string y are replaced with the
string z.
q)ssr["suffering succotash";"s";"th"] / Sylvester is from Madrid
"thuffering thuccotathh"
Tip
A useful idiom is ssr/ to replace multiple items.
q)(ssr/)["results_%div_%dept.csv"; ("%div";"%dept");
("banking";"m&a")]
"results_banking_m&a.csv"
Note
You cannot use * to match with ssr.
A.62 string
Use string to produce a string representation of any q entity. For
atoms, lists and functions, the result of string is a list of char
that does not contain any q formatting characters. Following are some
examples.
q)string 42
"42"
q)string `Zaphod
"Zaphod"
q)string 6*7
"42"
q)string 424224242i
"424224242"
q)string {[a] a*a}
"{[a] a*a}"
The first two examples demonstrate that string is not atomic
because the output does not conform to the input. Although string is not atomic, it does recurse into a list.
q)string 42 98
"42"
"98"
q)string (10 20; 30 40)
"10" "20"
"30" "40"
This accounts for the un-intuitive behavior of string on an actual
string.
q)string "Beeblebrox"
,"B"
,"e"
,"e"
,"b"
,"l"
,"e"
,"b"
,"r"
,"o"
,"x"
As expected, string acts on the values of a dictionary.
q)string ([a:10; b:20; c:30])
a| "10"
b| "20"
c| "30"
This is convenient for tables.
q)string ([] c1:`a`b`c; c2:10 20 30)
c1 c2
---------
,"a" "10"
,"b" "20"
,"c" "30"
Finally, string operates on the value portion of a keyed table.
q)string ([k:1 2 3] c:100 101 102)
k| c
-| -----
1| "100"
2| "101"
3| "102"
A.63 sublist
The binary sublist retrieves a sub-list of contiguous items from the
target list y, where x is either a non-negative integral count of
items to retrieve or a simple list of two non-negative integers
comprising the starting index and the count of items to retrieve.
q)3 sublist 10 20 30 40 50
10 20 30
q)1 3 sublist 10 20 30 40 50
20 30 40
q)6 sublist 10 20 30 40 50
10 20 30 40 50
q)2 sublist ([a:10; b:20; c:30])
a| 10
b| 20
Warning
The construct (n sublist ...) is preferred to (n# ...)
for extracting the first n items from a list since the latter will
repeat the initial items if necessary to reach the specified count. This
is ignored surprisingly often in practice.
q)6 sublist 10 20 30 40 50
10 20 30 40 50
q)6#10 20 30 40 50
10 20 30 40 50 10
A.64 sum sums msum
The aggregate sum is +/, which applies + cumulatively across a
numeric list and returns the final result. It is for those who like to
type more characters.
q)sum 1+til 100
5050
It is possible to apply sum to a nested list provided the sublists
conform. In this case, the result conforms to the sublists and the sum
is calculated recursively on the sublists.
q)sum (1 2;100 200;1000 2000)
1101 2202
The uniform sums is (+), which applies (+) cumulatively across a
list of numeric type and returns the intermediate results. It is for
those who like to type more characters.
q)sums 1+til 10
1 3 6 10 15 21 28 36 45 55
The binary msum takes a positive integer x and returns the
length-wide moving sum of the numeric list y. At each position in y,
it computes the sum of the x preceding items, or as many as are
available in the moving window up to that position. It excludes internal
nulls from the calculation.
q)3 msum 10 20 30 40 50
10 30 60 90 120
A.65 sv
The binary sv – "scalar from vector" – has several overloads. It is
usually written infix for ease of reading. Most of the overloads have
corresponding forms for sv.
The first form takes a char, a string (or the null symbol) x and a
list of strings y. It returns a string that is the concatenation of
the strings in y, joined with x.
q)"," sv ("Now";"is";"the";"time";"")
"Now,is,the,time,"
q)`$"," sv ("Now";"is";"the";"time";"")
`Now,is,the,time,
q)",," sv ("Now";"is";"the";"time";"")
"Now,,is,,the,,time,"
When sv is used with an empty symbol x and a list of symbols y,
the result is a symbol in which the items in x are concatenated with a
separating dot. This is useful for q context names.
q)` sv `qalib`stat
`qalib.stat
When sv is used with an empty symbol x and a symbolic list y whose
items comprise the parts of a file handle, the result is a symbol in
which the items in source are concatenated with a separating /.
This is useful for fully qualified path names.
q)` sv `:`q`tutorial`draft`3
`:/q/tutorial/draft/3
When sv is used with an empty symbol x and a list of strings y, it
concatenates the strings, inserting a new line character after each.
q)` sv ("abc";"de")
"abc\nde\n"
When sv is used with a long x that is greater than 1, together with
a simple list y of place values expressed in base x, the result is a
long representing the converted base 10 value.
q)2 sv 101010b
42
q)10 sv 1 2 3 4 2
12342
q)
q)256 sv 0x001092
4242
More precisely, the last version of sv evaluates the polynomial,
(d[n-1]*b exp n-1) + ... +d[0]
where d is the list of digits, n is the count of d, and b is the
base.
Thus, we find,
q)10 sv 1 2 3 11 2
12412
q)-10 sv 2 1 5
195
A.66 svar
The aggregate svar returns the statistical standard variance of its
numeric list x.
q)svar 2 3 5 7
4.916667
It is equivalent to
{var[x]*count[x]%-1+count x}
Important
The svar function was added in version 3.2 meaning that
Finance apps could no longer use a variable name svar for stress
value at risk in this and later versions.
A.67 system
Use system on a string x to execute a q command or to "shell out".
By this we mean q executes x if it is a q command, otherwise it is
passed to the OS for execution. This is convenient to execute q commands
or OS commands programmatically. The normal result of the command
becomes the return value of the evaluation.
Important
Do not include the initial \ as you would when
executing the command from the q session prompt.
q)system "c"
24 74i
q)system "c 20 200"
q)system "c"
20 200i
q)system "cd data" / this is q \cd which creates directory
q)system "pwd"
"/Users/jaborror/data"
A.68 # Take Reshape
The binary # has several overloads.
When x is an integer atom and y is an atom or list, Take returns x
items drawn from y. The items are extracted from the head when x is
positive and from the tail when x is negative. When x is zero, the
result is an empty list of the same type as the first item in y. The
result of take is always a list.
Important
When x is greater than the count of y, items of y
are recycled until x items are obtained.
q)2#10 20 30 40 50
10 20
q)-3#10 20 30 40 50
30 40 50
q)0#10 20 30 40 5
`long$()
q)3#42
42 42 42
q)10#10 20 30 40 5
10 20 30 40 5 10 20 30 40 5
Tip
The idiom 0#atom is a common way to create an empty list of
the type of atom.
q)meta ([] a:0#0; b:0#`)
c| t f a
-| -----
a| j
b| s
Since a dictionary is ordered, Take also applies to dictionaries and, by
extension, to tables and keyed tables.
q)2#([a:10; b:20; c:30])
a| 10
b| 20
q)-1#([] c1:`a`b`c; c2:10 20 30)
c1 c2
-----
c
q)2#([k:`a`b`c] v:10 20 30)
k| v
-| --
a| 10
b| 20
Observe that 1# does not convert a record dictionary into a table; you
must use enlist.
q)1#([a:10; b:20; c:30])
a| 10
q)enlist ([a:10; b:20; c:30])
a b c
--------
10 20 30
Another overload of Take has x a list of keys and y a dictionary.
The result is the sub-dictionary for the specified keys.
q)`a`c#([a:10;b:20;c:30])
a| 10
c| 30
Since a table is a column dictionary, this form also applies to a table and a list of column names.
q)`c1`c2#([] c1:`a`b`c; c2:10 20 30; c3:1.1 2.2 3.3)
c1 c2
-----
a 10
b 20
c 30
Using an anonymous table is a slick way to generate a list of keys for Take with a keyed table.
q)([] k:`a`c)#([k:`a`b`c] v:10 20 30)
k| v
-| --
a| 10
c| 30
The simple case of Reshape has x a list (r; c) of non-negative
integers and y a list or atom source. The result is a nested list
with r items, each having c items, drawn sequentially from the
beginning of source, repeatedly if necessary. Otherwise put, the
result is an r by c array obtained by reshaping source.
q)2 3#10 20 30 40 50
10 20 30
40 50 10
If in Reshape either ror c is null, the result is a nested list
obtained by reshaping y into the specified number of rows or columns.
This is generally a ragged array.
q)2 0N#10 20 30 40 50
10 20
30 40 50
q)0N 3#10 20 30 40 50
10 20 30
40 50
You can also use Reshape to create higher dimensional matrices although the null behavior only works in two dimensions.
q)2 3 4#til 24
0 1 2 3 4 5 6 7 8 9 10 11
12 13 14 15 16 17 18 19 20 21 22 23
A.69 tan atan
The atomic tan takes a float and returns its mathematical tangent.
q)tan 0
0f
q)pi:3.141592653589793
q)tan pi
-1.224647e-16
q)tan pi%2
1.633124e+16
q)tan pi%4
1f
The function tan is equivalent to:
(sin x)%cos x
The atomic atan is the mathematical inverse of tan. For a float
x, atan returns the float between – π/2 and π/2 whose tangent is
x.
q)atan 0
0f
q)atan 1.414213562373095
0.9553166
q)atan 1
0.7853982
A.70 til
Use til with non-negative integral x to return a list of x
consecutive longs starting with 0. The result is always a list
Tip
The result does not include x.
q)til 10
0 1 2 3 4 5 6 7 8 9
q)\t til 10000000
19
q)til 0
`long$()
q)til 1
,0
q)1+til 10
1 2 3 4 5 6 7 8 9 10
q)2*til 10
0 2 4 6 8 10 12 14 16 18
q)1+2*til 10
1 3 5 7 9 11 13 15 17 19
q).5*til 10
0 0.5 1 1.5 2 2.5 3 3.5 4 4.5
q)2025.01.01+til 5
2025.01.01 2025.01.02 2025.01.03 2025.01.04 2025.01.05
You can also use key in place of til.
q)key 10
0 1 2 3 4 5 6 7 8 9
A.71 trim ltrim rtrim
Use ltrim to remove leading nulls from a list. For strings it removes
leading banks.
q)ltrim 0N 20 30 0N 0N
20 30 0N 0N
q)ltrim " abc "
"abc "
q)ltrim " "
""
You can also apply ltrim to a non-blank char but it fails for a blank
char (why?).
q)ltrim"a"
"a"
q)ltrim" "
'type
Use rtrim to remove trailing nulls from a list. For strings this
removes trailing blanks.
q)rtrim 0N 20 30 0N 0N
0N 20 30
q)rtrim " abc "
" abc"
q)rtrim " "
""
You can apply rtrim to a non-blank char but it fails for a blank char.
q)rtrim "a"
"a"
q)rtrim " "
'type
[0] rtrim " "
^
trim to remove both leading and trailing nulls from x. For strings
the removes leading and trailing blanks.
q)trim 0N 20 30 0N 0N
20 30
q)trim " abc "
"abc"
q)trim " "
""
The function trim is equivalent to:
{ltrim rtrim x}.
A.72 ungroup
Use ungroup to flatten the result of xgroup or a select ... by
without aggregation. You can also apply ungroup to tables with nested
columns of the same form that are otherwise generated.
The action of ungroup expands each key group, resulting in one row for
each item in the nested columns. The fields in a result row are drawn
from corresponding positions across the nested columns.
We use the distribution example.
q)\l sp.q
q)sp
s p qty
---------
s1 p1 300
s1 p2 200
s1 p3 400
s1 p4 200
s4 p5 100
s1 p6 100
s2 p1 300
s2 p2 400
s3 p2 200
q)select s, qty by p from sp
p | s qty
--| -------------------------------
p1| `s$`s1`s2 300 300
p2| `s$`s1`s2`s3`s4 200 400 200 200
p3| `s$,`s1 ,400
p4| `s$`s1`s4 200 300
p5| `s$`s4`s4 100 400
p6| `s$,`s1 ,100
q)ungroup select s, qty by p from sp
p s qty
---------
p1 s1 300
p1 s2 300
p2 s1 200
p2 s2 400
p2 s3 200
p2 s4 200
p3 s1 400
p4 s1 200
p4 s4 300
p5 s4 100
p5 s4 400
p6 s1 100
q)`p xgroup sp
p | s qty
--| -------------------------------
p1| `s$`s1`s2 300 300
…
q)ungroup `p xgroup sp
p s qty
---------
p1 s1 300
p1 s2 300
…
Tip
Observe that ungroup is not quite the inverse of a grouping
operation. Since grouping sorts on the keys, a subsequent ungroup
returns the original records sorted by the grouped column(s).
A.73 value
Simply put, value runs the q interpreter on a string argument.
Tip
The functions value and get are identical since they are
both unary (.) in k. Conventionally get is used with file I/O.
When value is applied to a symbol, it returns the value associated
with the variable of that symbolic name. In a fresh q session,
q)value `a
'a
q)a:42
q)value `a
42
When applied to a dictionary, value returns the values portion of
the dictionary.
q)value ([a:10; b:20; c:30])
10 20 30
q)value ([k:`a`b`c] v:10 20 30)
v
--
10
20
30
Tip
A common idiom uses value to extract the columns lists from
a table.
q)value flip ([] c1:`a`b`c; c2:10 20 30)
a b c
10 20 30
When value is applied to an enumerated value, it de-enumerates it.
This is handy when switching between kdb+ databases having different sym
domains. In a fresh q session,
q)ev:`sym?`a`x`b`y`a`c`b
q)ev
`sym$`a`x`b`y`a`c`b
q)value ev
`a`x`b`y`a`c`b
Given a function, value returns the following list:
(bytecode;parameters;locals;(namespace,globals);constants[0];...;constants[n];m;n;f;l;s)
where
| Item | Description |
|---|---|
m |
Bytecode to source position map; -1 if position unknown |
n |
Fully qualified (with namespace) function name as a string, set on first global assignment, with @ appended for inner lambdas; () if not applicable |
f |
Full path to the file where the function originated from; "" if not applicable |
l |
Line number in said file; -1 if not applicable |
q)f:{[a;b]d::neg c:a*b+42;c+e}
q)value f
`a`b
,`c
``d`e
42
21 19 20 17 18 0 16 11 0 9 0 9 0 26 24 25 2 2
"..f"
""
-1
"{[a;b]d::neg c:a*b+42;c+e}"
Given a view alias, value returns the list:
(cached value;parse tree;dependencies;definition)
When the evaluation of the expression in the alias is as yet deferred,
the cached value is ::.
q)a:42
q)b::a+1 / evaluation is deferred
q)value `.[`b] / inspect b in global context
::
`s#(+;`a;1)
,`a
(("q";`);"";0;"b::a+1")
q)b
43
q)value `.[`b]
43
`s#(+;`a;1)
,`a
(("q";`);"";0;"b::a+1")
Given a projection, value returns a list containing the function body
followed by the supplied arguments.
q)value f[2;3;]
{x+y+z}
2
3
::
Given a function that is the result of applying a unary iterator,
value returns the argument to the iterator, viewing the latter as a
higher order function.
q)value (+/)
+
q)value (+')
+
q)f:{x+y}
q)value (f')
{x+y}
The final and most powerful form of value is: when applied to a string
it is the q interpreter itself.
q)value "6*7"
42
q)value "{x*x} til 10"
0 1 4 9 16 25 36 49 64 81
It will also evaluate some parse trees – i.e., a (potentially) nested
list of functions followed by arguments – but it is better to use eval
for this purpose.
q)value (*; 6; 7)
42
q)f:{x*y}
q)value (`f; 6; 7)
42
Important
The use of the value function is a powerful feature
that allows q code to be written and executed on the fly. This can
expose your program to potential attack unless done very carefully. If
abused, it can quickly lead to unmaintainable code. (The spellchecker
suggests "unmentionable" instead of "unmaintainable." How did it
know?)
A.74 var
The aggregate var takes a numeric list and returns the mathematical
variance of the items as a float.
q)var 42 45 37 38
10.25
The function var is equivalent to:
{(avg[x*x]) - (avg[x])*(avg[x])}
A.75 vs
The binary vs – 'vector from scalar' – has several overloads. It is
usually written infix for ease of reading. Most of the overloads have
corresponding forms for sv.
The first form takes a char or string x and a string y. It
returns a list of strings containing the tokens of y as delimited by
the specified x.
q)" " vs "Now is the time "
"Now"
"is"
"the"
"time"
""
q)", " vs "nuba, devi, lorenzo"
"nuba"
"devi"
"lorenzo"
Tip
You probably want to trim the input in the first example.
When x is an empty symbol and y is a symbol containing one of more
., vs returns a simple symbol list obtained by splitting y along
the dots.
q)` vs `qalib.stat
`qalib`stat
Where x is the empty symbol `, and y is a string or bytestream,
vs returns as a list of strings from y partitioned on embedded line
terminators. (It recognizes both Unix \n and Windows \r\n
terminators).
q)` vs "abc\ndef\nghi"
"abc"
"def"
"ghi"
q)` vs "x"$"abc\ndef\nghi"
"abc"
"def"
"ghi
When vs is used with an empty symbol x and a symbol representing a
fully qualified file name y, it returns a simple list of two symbols
in which the first item is the path and the second item is the file
name. Note that in this usage, vs is not quite the inverse of sv.
q)` vs `:/Users/jaborror/Q4M/example.dat
`:/Users/jaborror/Q4M`example.dat
When y is a byte vector, x can be a delimiter byte or byte vector.
q)0x02 vs 0x0102010201
,0x01
,0x01
,0x01
q)0x0203 vs 0x000102030405
0x0001
0x0405
q)" "vs"x"$"a b" / type inferred from left hand side
,"a"
,"b"
When vs is used with x as 0b or 0x00 and y is a value of integral
type, it returns a simple list whose items comprise the digits of the
corresponding binary representation of source.
q)0x00 vs 4242
0x0000000000001092
q)10h$0x00 vs 8151631268726338926j
"q is fun"
q)0b vs 42
0000000000000000000000000000000000000000000000000000000000101010b
The 0b version can be used to display the internal representation of
special values.
q)0b vs 0W
0111111111111111111111111111111111111111111111111111111111111111b
q)
q)0b vs -0W
1000000000000000000000000000000000000000000000000000000000000001b
A.76 wavg
The binary wavg takes two conforming numeric lists and returns the
float average of y weighted by x in corresponding positions.
q)1 2 3 4 wavg 500 400 300 200
300f
q)(1 2;3 4) wavg (500 400; 300 200)
350 266.6667
The function wavg is equivalent to,
{(sum x*y)%sum x}
A.77 where
The unary where has two use cases.
The first returns the indices of 1b in a boolean list, or the keys
associated to 1b in a dictionary with boolean values.
q)where 101010b
0 2 4
q)where `a`b`c`d`e`f!101010b
`a`c`e
This is useful when the boolean mapping is the result of a predicate.
q)L:"First, second, third"
q)where L=","
5 13
q)@[L; where L=","; :; "\t"]
"First\t second\t third"
q)where null ([a:1;b:0N;c:4;d:0N;f:6])
`b`d
In the more general case, the argument of where is a list x of
non-negative integers, and the result is a list having x[i] copies
of i for each index of x.
q)where 2 1 0 3 2
0 0 1 3 3 3 4 4
q)where 4#1
0 1 2 3
Zen Moment
The second form of where generalizes the form on a boolean list.
Even more generally, where works on dictionaries in an consistent way.
q)where`a`b`c!3 2 3
`a`a`a`b`b`c`c`c
A.78 within
The binary within is atomic in x and has y a list whose two items
are comparable. It returns a boolean representing whether x is greater
than or equal to y[0] and less than or equal to y[1]. It does
type promotion on arguments.
q)3 within 2 5
1b
q)(til 7) within 2 5
0011110b
q)"c" within "az"
1b
q)2025.03.14 within 2025.02.01 2025.03.21
0b
q)`ab within `a`b
1b
q)100 within "aj"
1b
Tip
Ensure the items in the second argument are in increasing order or you will get no matches.
A.79 wsum
The binary wsum takes two conforming numeric lists and returns the
float sum of the items of y weighted by the items of the x.
q)1 2 3 4 wsum 500 400 300 200
3000f
The function wsum is equivalent to,
{sum x*y}
Tip
This is the vector dot product.
A.80 xbar
The binary xbar takes a non-negative numeric atom x and is atomic in
the numeric y. It returns the largest integral multiple of x that is
less than or equal to y. Visually, the result is the left endpoint of
the band of width x that contains y. Since xbar is atomic in the
second parameter, this is an effective way to bin the items in a numeric
list.
q)1 xbar 0 .5 1 1.5 2 2.5 3 3.5
0 0 1 1 2 2 3 3f
q)2 xbar 0 .5 1 1.5 2 2.5 3 3.5
0 0 0 0 2 2 2 2f
Since a q month is the count of months since the millennium, you can use
xbar to determine quarters. Recall that a month is equal to the first
day of the month.
q)`date$3 xbar `month$2025.11.19 / beginning of that quarter
2025.10.01
q)`date$3+3 xbar `month$2025.11.19 / beginning of next quarter
2026.01.01
q)-1+`date$3+3 xbar `month$2025.11.19 / end of that quarter
2025.12.31
A.81 xrank
The binary xrank takes x a positive integer and is uniform on the
list y. It returns a list of integers containing the x-quantile into
which each item of y falls, considering y as a distribution. For
example, choosing x to be 4 returns quartiles and 100 yields
percentiles.
q)4 xrank 30 10 40 20 90
1 0 2 0 3
q)100 xrank 200?1000.
338 55 54 40 18 30 83 56 74 42 52 61 9 20 35 64 55 73 22 73 50 66 97 ..