Skip to content

Views

A view is a calculation that is re-evaluated only if the values of the underlying dependencies have changed since its last evaluation.

Why use a view?

Views can help avoid expensive calculations by delaying propagation of change until a result is demanded.

How is a view defined?

Views and their dependencies can be defined only in the default namespace.

The syntax for the definition is

q)viewname::[expression;expression;…]expression

Terminating semicolon

The result returned by a view is the result of the last expression in the list, just as in a lambda.

q)a: til 5
q)uu:: a
q)uu
0 1 2 3 4
q)vv:: a;
q)vv
q)vv ~ (::)
1b
q)vv ~ {[];}[]
1b

The following defines a view called myview which depends on vars a and b.

q)myview::a+b
q)a:1
q)b:2
q)myview
3

Defining a view does not trigger its evaluation.

A view should not have side-effects, i.e. should not update global variables. Although ; is permitted at the end of the definition, it would mean the view returns (::). As a view should have no side-effects, returning (::) would make the purpose of the view redundant.

A view definition can be spread over multiple lines in a script as long as it is indented accordingly (e.g. exactly like a function definition). e.g.

$ cat v.q
t:([]a:til 10)
myview::select from t
 where a<5 / note this line is indented by one space
$ q v.q
KDB+ 3.2 2014.08.26 Copyright (C) 1993-2014 Kx Systems
m64/...
q)myview
a
-
0
1
2
3
4

Within a lambda, :: amends a global variable. It does not define a view.

q)x:2
q)y:3
q)v::x+y           /view
q)v
5
q)x:10000
q)v                /depends on x
10003
q){v::x+y}[10;20]  /v now a global variable
q)v
30
q)x:-1000000
q)v                /global variable, no longer depends on x
30

How to list views

Invoke the views function (or \b) to get a list of the defined views.

q)a::b+c
q)d::b+a
q)views`
`s#`a`d

How to list invalidated views

Invalidated (pending) views are awaiting recalculation.

Invoking \B will return a list of pending views.

q)a::b+c
q)\B
,`a
q)b:c:1
q)\B
,`a
q)a
2
q)\B
`symbol$()

Splayed tables

To use views with splayed tables make sure you invalidate the data when it changes; this can be done for example by reloading the table.

How to see the definition of a view

The text definition of a view can be seen with view `viewname.

q)a::b+c
q)view`a
"b+c"

The following view command has the form `. `viewName. Note the space between `. and `viewname.

q)d::b+a
q)`. `d
b+a

value on that reveals the underlying representation:

  • (last result|::)
  • parse-tree
  • dependencies
  • text
q)value`. `d
::
(+;`b;`a)
`b`a
"b+a"

If previously evaluated, the last result can be seen here as the first element.

q)b:1;a:2
q)d
3
q)value`. `d
3
(+;`b;`a)
`b`a
"b+a"

A view which uses select/exec/update/delete is worth mentioning as it may not be immediately obvious what dependencies are present. e.g. in the following example, t is the only dependency, as a and b may be columns in t, or globals – this is not known until the select is evaluated and hence cannot be inferred as dependencies.

q)v::select from t where a in b
q)value`. `v
::
(?;`t;,,(in;`a;`b);0b;())
,`t
"select from t where a in b"

If a or b are globals to be dependencies, a workaround is for these is to be mentioned at the beginning of the definition, e.g.

q)v::a;b;select from t where a in b
q)value`. `v
::
(";";`a;`b;(?;`t;,,(in;`a;`b);0b;()))
`a`b`t
"a;b;select from t where a in b"

If a function is used within a view, that does not become a dependency. The following view would not be invalidated unless the f were redefined.

q)v::f[]+1
q)f:{42}
q)v
43
q)value`. `v
43
(+;(`f;::);1)
,`f
"f[]+1"

Self-referencing views

Self-referencing views are allowed since V3.2. A self-referencing view is a view that includes itself as part of the calculation. In such a case, the view uses its previous value as part of the evaluation if it exists, otherwise it signals 'loop. e.g.

q)v::$[b;1;v+1]
q)b:1;0N!v;b:0;v
q)v::$[b;1;v+1]
q)v
'loop

From V3.2 view-loop detection is no longer performed during view creation; it is checked during the view recalc.

Dot notation

Views do not support dot notation.

q)t:.z.p
q)t1::t
q)t.date
2014.09.03
q)t1.date
'nyi

Multithreading

Views must be evaluated on the main thread, otherwise the calculation will signal 'threadview. E.g. with q using two secondary threads

$ q -s 2
KDB+ 3.2 2014.08.26 Copyright (C) 1993-2014 Kx Systems
m64/...
q)a::b+c
q)b:c:1
q){a}peach 0 1
k){x':y}
'threadview
@
{a}':
0 1
q.q))\
q)a
2
q){a}peach 0 1
2 2

Parse

Views are not parsable, e.g. eval parse "a::b+c"


view, views, .z.b, .z.vs
\b, \B
Q for Mortals §9.11 Views