cancel
Showing results for 
Search instead for 
Did you mean: 

Question on Contexts

erik_friis
New Contributor
I read the section in Borror's book on contexts.

Is there any more definitive documentation on contexts anywhere?

Let's say I execute the two expressions:

.erik.myVar : 2.718

.erik.friis.myVar : 3.14

This should create the context .erik and a context in that called .erik.friis, both containing variables called myVar with different values.

How do you navigate to the "friis" context using \d from the root context "." ?  It seems that even when in "erik" key ` lists the contexts in "."

Is there a way to specify "get a value from the parent context of a given context" such as using ".." in a path?

Thanks.
7 REPLIES 7

erik_friis
New Contributor
Thanks Charles.  That's actually the section in Borror's book that I read and didn't find it too forthcoming.  I was hoping there might be some more complete or user friendly documentation somewhere.  E.g. is there a way to access the parent context etc.

charlie
New Contributor II
New Contributor II
that page contains the answers, but you do have to think about it.

Charles:
I guess the whole point of providing free access to a product and trying to grow a user community is to try to help, not just tell people to go read it again. I know I had trouble going through a lot of the available documentation because its dispersed though a lot of pages and its difficult to get a big picture of how things interconnect until you do a lot of digging.
If users have a hard time understanding some of the documentation perhaps that is an indication that it could be improved, either on substance or readability.
Please note that I'm not trying to pick a fight. Its just my humble opinion.

Erik:
Back to the original question. 
No, you can't change directories in a hierarchical fashion with \d, but its trivial to write a function analogous to 'cd ..' (change to upper level directory). This is arguably useless, since q does not allow you to change directories beyond the first level. 
If you want to play with the idea, you can get the current directory into a variable with c:value"\\d", and call \d from inside a function with eval parse "\\d ", dir 


Regarding the directory structure, its a tree built of nested dictionaries. For instance:

q).d1.a:1

q)0N!value `.d1

``a!(::;1)

 | ::

a| 1


  Note the first element is a null. Now if we  create a subdirectory, you get a nested dictionary:

q)0N!value `.d1

``a`d2!(::;1;``a!(::;1))

  | ::

a | 1

d2| ``a!(::;1)


And so on, for an arbitrarily deep nesting.


A final interesting thing to note on directories is that functions are dependent on the context they were created. The persistence is achieved because the function serialises the context in which it was created.


/ Function g defined in root directory:

q).aaa.g:{a+x}


/ Function h defined in aaa directory:

q)\d .aaa

q.aaa).aaa.h:{a+x}


Function g will always refer to the variable a on root directory and h on directory 'aaa'.

You can see how this is handled behind the covers by inspecting the IPC byte representation of both functions:


q)-8!.aaa.g

0x010000001500000064000a00050000007b612b787d


Endianess: 1 (little endian)

Length: 15

Type: 0x64 (100 - lambda)

Context: 00 (root)

Type: 0x0a (character vector)

Attributes: 0x0

Vector len: 5

Vector: 0x7b612b787d (“{a+x}”)


q)-8!.aaa.h

0x010000001800000064616161000a00050000007b612b787d


Endianess: 1 (little endian)

Length: 18

Type: 0x64 (100 - lambda)

Context: 0x61616100 (“aaa\0”)

Type: 0x0a (character vector)

Attributes: 0x0

Vector len: 5

Vector: 0x7b612b787d (“{a+x}”)


Regards,


Tiago

charlie
New Contributor II
New Contributor II

namespaces are built from dicts where the key is a vector of symbols, and there is a map from ` to (::).


views (and .z.vs) work with data in root context only.

q).z.vs:{0N!(x;y);}
q)a.d:4
(`a.d;())
q)a.b:1
(`a.b;())
q).a.b:1


btw, the context in which a function was defined is visible using value fn

q)\d .aaa
q.aaa)h:{a+x}
q.aaa)value h
0x7881410003
,`x
`symbol$()
`aaa`a
"{a+x}"

q.aaa)\d .
q)h:{a+x}
q)value h
0x7881410003
,`x
`symbol$()
``a
"{a+x}"

as documented at
http://code.kx.com/wiki/Reference/value

"Given a function, it returns the list
(bytecode;parameters;locals;(context;globals);constants[0];...;constants[n];definition)"



No, you can't change directories in a hierarchical fashion with \d, but its trivial to write a function analogous to 'cd ..' (change to upper level directory). This is arguably useless, since q does not allow you to change directories beyond the first level. 
If you want to play with the idea, you can get the current directory into a variable with c:value"\\d", and call \d from inside a function with eval parse "\\d ", dir 


Regarding the directory structure, its a tree built of nested dictionaries. For instance:

q).d1.a:1

q)0N!value `.d1

``a!(::;1)

 | ::

a| 1


  Note the first element is a null. Now if we  create a subdirectory, you get a nested dictionary:

q)0N!value `.d1

``a`d2!(::;1;``a!(::;1))

  | ::

a | 1

d2| ``a!(::;1)


And so on, for an arbitrarily deep nesting.


A final interesting thing to note on directories is that functions are dependent on the context they were created. The persistence is achieved because the function serialises the context in which it was created.


/ Function g defined in root directory:

q).aaa.g:{a+x}


/ Function h defined in aaa directory:

q)\d .aaa

q.aaa).aaa.h:{a+x}


Function g will always refer to the variable a on root directory and h on directory 'aaa'.

You can see how this is handled behind the covers by inspecting the IPC byte representation of both functions:


q)-8!.aaa.g

0x010000001500000064000a00050000007b612b787d


Endianess: 1 (little endian)

Length: 15

Type: 0x64 (100 - lambda)

Context: 00 (root)

Type: 0x0a (character vector)

Attributes: 0x0

Vector len: 5

Vector: 0x7b612b787d (“{a+x}”)


q)-8!.aaa.h

0x010000001800000064616161000a00050000007b612b787d


Endianess: 1 (little endian)

Length: 18

Type: 0x64 (100 - lambda)

Context: 0x61616100 (“aaa\0”)

Type: 0x0a (character vector)

Attributes: 0x0

Vector len: 5

Vector: 0x7b612b787d (“{a+x}”)


Regards,


Tiago


On Monday, 22 June 2015 16:55:03 UTC+1, Charles Skelton wrote:
that page contains the answers, but you do have to think about it.

--
You received this message because you are subscribed to the Google Groups "Kdb+ Personal Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to personal-kdbplus+unsubscribe@googlegroups.com.
To post to this group, send email to personal-kdbplus@googlegroups.com.
Visit this group at http://groups.google.com/group/personal-kdbplus.
For more options, visit https://groups.google.com/d/optout.

erik_friis
New Contributor
OK, I re-read it.  It seems that the current context implementation is very basic, but that's OK--sometimes less is more.

erik_friis
New Contributor
Tiago:

Thank you for the long and very informative reply!  I appreciate all of the extra detail.


Charles:

I appreciate your post with the addition information.