The first time we needed a column that can hold values of multiple types, we tried something similar to the following:

q)t: ([] thing: ())
q)meta t
c    | t f a
—–| —–
thing|
q)

True, when you define a table column as an untyped list, it can contain anything. However, the first time you put something in it, the column’s type is set to the type of that first inserted item:

q)`t insert `aunt
,0
q)`t insert 33.33
‘type
q)meta t
c    | t f a
—–| —–
thing| s

In our example, the type of the thing column has been promoted to symbol; we can’t insert numbers into it.

When you want to store elements of different types in the same column, you have to prevent q from performing this type promotion by stuffing a sentinel row (i.e., a row of dummy values), whose value for the column in question is itself a list, into the table:

q)t: ([] thing: enlist “sentinel”)
q)meta t
c    | t f a
—–| —–
thing| C

Don’t believe the hype. The meta function is trying to help out by actually inspecting the first value in the column when reporting the thing column’s type. However, the true type of the column is untyped, i.e., zero:

q)type t `thing
0h
q)

You can, therefore, put whatever you like into t’s thing column:

q)`t insert/: (`gave; 42)
1
2
q)t
thing
———-
“sentinel”
`gave
42
q)meta t
c    | t f a
—–| —–
thing| C
q)

Beware cleaning out such a table too thoroughly (in, say, an end-of-day function):

q)delete from `t
`t
q)meta t
c    | t f a
—–| —–
thing|
q)

See this related faq on untyped lists.

mod 1000:

q)now: .z.T
q)now
00:15:00.812
q)now mod 1000
00:00:00.812

If you want the milliseconds as an integer, you can simply follow the mod with a conversion to int:

q)`int$ now mod 1000
812

You don’t want to pass a datetime to mod; the result you’ll get is not what you had in mind. You must convert it to a time first:

q)now: .z.Z
q)now
2011.03.26T09:51:26.624
q)now mod 1000
102.4107
q)`int$ (`time$ now) mod 1000
624
q)

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
0N
q)

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
0N
q)(::) ~ NullOf {x*x}
1b
q)null NullOf (.z.D; 1e; ” “; type “foo”)
1111b
q)

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
`int$()
q)

See also: .Q.ty