QforMortals2/workspace organization

From Kx Wiki
Jump to: navigation, search

Contents

Workspace Organization

Overview

The collection of entities that exist in a q session comprises the workspace. In other words, the workspace includes all atoms, lists, dictionaries, functions, enumerations, etc., that have been created through the console or via script execution.

Any programming environment of reasonable complexity has the potential for name clashes. For example, should two separate q scripts both create a variable called 'foobar', one will overwrite the value of the other. Variable typing is of no help here, since a variable can be reassigned with a different type at any time.

The solution to name clashes is to create namespaces. This is accomplished with a hierarchical naming structure implemented with a separator character, usually a dot or a slash. For example, the name spaces A and B can both have an entity foobar , yet A.foobar and B.foobar are distinct. A familiar example of this is the hierarchical directory/file system used by operating systems.

Namespaces in q are called directories or contexts. Contexts provide an organization of the workspace.

Contexts

The q workspace provides a simple namespace structure using dot notation for entity names. Each of the nodes is called a context, or a directory. The default context, also called the root, comprises all entities whose names start with an initial alpha character. The variables we have created heretofore have resided in the default context.

Context Notation

A context name has the form of a dot ( . ) followed by alphnums, starting with an alpha. The following are all valid context names.

        .a
        .q
        .z0
        .zaphod

There is no need to pre-declare the context name. As in the case of variables, a context is created dynamically as required. You specify a variable to a context by prepending the context name to the variable name, separated by a dot ( . ). The variable foobar can be created in various contexts,

        foobar:42
        .aa.foobar:43
        .z0.foobar:45
        .zaphod.foobar:46

Variables of the same name in different contexts are indeed distinct,

        foobar
42
        .aa.foobar
43
        .z0.foobar
45
        .zaphod.foobar
46

When an entity name includes its full context name, we say the name is fully qualified. When an entity name omits the context name, we say the name is unqualified.

Reserved Contexts

All contexts of a single letter (both lower and upper case) are reserved for q itself. Some of these are listed below:

Name Use
.q Built-in functions
.Q Low-level routines used by q
.z Environmental interaction
Warning.png Important: While q will not prevent you from placing entities in the reserved contexts, doing so risks serious problems should you collide with names used by q.

Working with Contexts

At any time in a q session, there is a current or working context. When you start a q session, the current context is the default context. You change the current context with the \d command. For example, to switch to the 'files' context,

        \d .files

To switch back to the default context,

        \d .

To display the current context,

        \d
`.

Any entity in the current context can be specified using its unqualified name.

        \d .                / switch to default context

        .files.home:`c:
        .files.home
`c:
        \d .files
        home
`c:

A Context is a Dictionary

A context is actually a sorted dictionary whose domain is a list of symbols with the names of the entities defined in the context. Apply the key function to the dictionary name to display the names of the entities in the context. Apply value to see the entire dictionary mapping.

        .new.a:42
        .new.L:1 2 3
        .new.d:`a`b`c!1 2 3
        key `.new
``a`L`d

        value `.new
 | ::
a| 42
L| 1 2 3
d| `a`b`c!1 2 3

Observe that q places an entry into any non-default context that maps the null symbol to the null item.

You can look up an entity name in the directory to get its associated value. Use a symbol containing the context name to refer to the dictionary.

        `.new[`L]
1 2 3
Warning.png Note: In order to access an entity in the default context from another context, you must retrieve the value from the context dictionary. There is no syntactic form.
        \d .
        ztop:42
        \d .new
        `.[`ztop]
42

Expunging from a Context

We have seen that a context is a directory that maps entity names for the context to their values. This means that in order to expunge an entity from a context, we can simply delete it from the dictionary.

For example, if we can define a variable a in the context .new and then remove it from the workspace when it is no longer needed. Observe that we use the symbolic name of the context to ensure that the delete is applied to it by reference.

	.new.a:42
	.new
 | ::
a| 42
	/
	/ do some work ...
	/
	delete a from `.new
`.new
	.new
| ::

In particular, to expunge a global entity from the default context, use `. as the directory name. In a fresh workspace we find,

	a:42
	b:98.6
	c:`life
	\v
`s#`a`b`c
	delete a from `.
`.
	\v
`s#`b`c

Functions and Contexts

Function definition presents an issue with respect to global variable references and unqualified names. In the following function, the variable a is an unqualified global variable,

        f:{a+x}

There is a potential ambiguity with respect to the context of a. Is the context resolved at the time f is defined, or is it resolved at the time f is evaluated?

Warning.png Important: The context of an unqualified global variable in a function is the context in which the function is defined, not the context in which it is evaluated.

Thus, we find

        \d .
        a:42
       \d .lib
       f:{a+x}
       f[6]
{a+x}
'a
)\

        a:100
        f[6]
106

        \d .
        .lib.f[6]
106

We also find the following result, because even though g lives in the .lib context, it is defined in the default context.

        \d .
        .lib.g:{a*x}
        a:42
        g[2]
'g

        \d .lib
        g[3]
126
        a:6
        g[7]
294

Namespaces (Advanced)

It is possible to simulate a multi-level namespace hierarchy by using multiple dots in names.

        .lib1.vars.op1:6
        .lib1.vars.op2:7
        .math.fns.f:{x*y}
        .math.fns.f[.lib1.vars.op1;.lib1.vars.op2]
42

In the example above, q creates dictionaries at each node of the tree.

 #!q
       value `.lib1.vars
   | ::
op1| 6
op2| 7
        value `.math.fns
 | ::
f| {x*y}

But appearances are deceiving. As of this writing (Jan 2007), q does not recognize a context tree below the first level. So, in our example, you can not switch to a context .lib1.vars using the \d command.

        \d .math.fns
'.math.fns

You must access the contents of a node dictionary below the top level functionally.

        `.math.fns[`f] [6;7]
42

The following is arguably more readable.

        mlib:`.math.fns
        mlib[`f][6;7]
42

        vlib:`.lib1.vars
        vlib[`op1`op2]
6 7
        mlib[`f] . vlib[`op1`op2]
42

This is one way to perform late-bound computation using members in the context tree.


Prev: I/O Next: Commands and System Variables

Table of Contents

©2006-2007 Kx Systems, Inc. and Continuux LLC. All rights reserved.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox