I can create two namespaces, .a and .b:q)\d .aq.a)f:{g}q.a)g:{showhello}q.a)\d .q).b.f:{g[]}q).b.g:{show
hello}The namespaces appear to be identical, but internally they’re not:q).Q.s1[.a]~.Q.s1 .b1bq).a~.b0bAnd when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:q).a.f`helloq).b.f{g}'gWhy the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?Thanks,Rob
You can have a look at the internals of the function:
http://code.kx.com/wiki/Reference/value
(at the valuing of a function part)
You can see the differences at the (context;globals) part of the result with this quick approach:
cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]
cont glob | |
---|---|
.a.f | a g |
.b.f | g |
Telling you .b.f is looking for g in the root context and hence your error.
HTH,
Sean
Perfect. Thanks!
28.11.2016, 10:54, “Sean O’Hagan” <sohagan@firstderivatives.com>:
You can have a look at the internals of the function:
http://code.kx.com/wiki/Reference/value
(at the valuing of a function part)You can see the differences at the (context;globals) part of the result with this quick approach:
cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]
cont glob .a.f a g .b.f g Telling you .b.f is looking for g in the root context and hence your error.
HTH,
SeanOn Monday, November 28, 2016 at 10:12:47 AM UTC, Rob Smith wrote:
I can create two namespaces, .a and .b:
q)\d .a
q.a)f:{g}
q.a)g:{showhello} q.a)\d . q).b.f:{g[]} q).b.g:{show
hello}The namespaces appear to be identical, but internally they’re not:
q).Q.s1[.a]~.Q.s1 .b
1b
q).a~.b
0bAnd when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:
q).a.f
`hello
q).b.f
{g}
'gWhy the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?
Thanks,
Rob
–
Submitted via Google Groups
Look at this as link as well- http://code.kx.com/wiki/JB:QforMortals/workspace\_organization#Functions\_and\_Contexts
It has some good examples.
From the link - “The context of an unqualfied global variable in a function is the context in which the function is defined, not the context in which it is evaluated.”
On Monday, 28 November 2016 11:35:54 UTC, Rob Smith wrote:
Perfect. Thanks!
28.11.2016, 10:54, “Sean O’Hagan” <soh…@firstderivatives.com>:
You can have a look at the internals of the function:
http://code.kx.com/wiki/Reference/value
(at the valuing of a function part)You can see the differences at the (context;globals) part of the result with this quick approach:
cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]
cont glob .a.f a g .b.f g Telling you .b.f is looking for g in the root context and hence your error.
HTH,
Sean
Thanks. So is there any way to modify a table in a non-default context using its unqualified name? For example, say I have two tables and a function defined in the .ex context: \d .ex asks:bids:([]buy:0#1b; id:0#0Ng; px:0#0n; qty:0#0n) addOrder:{$[x`buy;`bids;`asks]upsert x} When I run addOrder `buy`id`px`qty!(1b;rand 0Ng;12.34;100f) the order isn't upserted into .ex.bids. Even though the function is defined in the .ex context, bids is modified in the default context.
28.11.2016, 15:03, “RAHUL ASATI” <rahul.asati04@gmail.com>:
Look at this as link as well- http://code.kx.com/wiki/JB:QforMortals/workspace_organization#Functions_and_Contexts
It has some good examples.
From the link - “The context of an unqualfied global variable in a function is the context in which the function is defined, not the context in which it is evaluated.”
On Monday, 28 November 2016 11:35:54 UTC, Rob Smith wrote:
Perfect. Thanks!
28.11.2016, 10:54, “Sean O’Hagan” <soh…@firstderivatives.com>:
You can have a look at the internals of the function:
http://code.kx.com/wiki/Reference/value
(at the valuing of a function part)You can see the differences at the (context;globals) part of the result with this quick approach:
cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]
cont glob .a.f a g .b.f g Telling you .b.f is looking for g in the root context and hence your error.
HTH,
SeanOn Monday, November 28, 2016 at 10:12:47 AM UTC, Rob Smith wrote:
I can create two namespaces, .a and .b:
q)\d .a
q.a)f:{g}
q.a)g:{showhello} q.a)\d . q).b.f:{g[]} q).b.g:{show
hello}The namespaces appear to be identical, but internally they’re not:
q).Q.s1[.a]~.Q.s1 .b
1b
q).a~.b
0bAnd when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:
q).a.f
`hello
q).b.f
{g}
'gWhy the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?
Thanks,
Rob
–
Submitted via Google Groups
Which version are you using? If you run that from .ex context that should work. Its working for me.
Another behavior to note is that variables referenced using backtick inside function are parsed as constants (use value on function to get details) and constants are read/write in the context in which function is executing.
Ex:
q) a:2 // root context
q) \d .ex
q.ex) a: 3 // .ex context
q.ex) f:{get[`a]+1}
q.ex) f // output - 4 (read from .e context)
q.ex)\d .
q) .ex.f // output - 3 read from root context
Above behavior also applies to tables with backticks (ex: when used in insert/upsert commands). So make sure that function is getting executed in correct context as that could corrupt data in other workspace if there is a table with same name(and schema).
all reference to named variables are evaluated in the global context.
to modify the .ex.bids and .ex.asks tables, change your function to:
addOrder:{$[x`buy;`.ex.bids;`.ex.asks]<wbr>upsert x}<br></wbr>
or perhaps:
addOrder:{(`.ex.asks`.ex.buy x`buy)<wbr>upsert x}<br><br></wbr>
i would, however, not store data in the .ex directory. directories are for code and configuration variables
you can have a parallel 'ex' namespace to store your data:
ex.bids and ex.asks
that would allow you to create views on your data (which are not possible in directories).
I’m using 3.4 and can reproduce your example, so I don’t think it’s a bug.
I was expecting f to return the same result regardless of from what context it was called. When using a variable directly, as in g below, the context used for variable lookups is always that in which the function was defined. But I guess that is not possible when using a variable by referencing its symbol name.
So if I want to modify a table defined in a non-default context using a function that may be called from another context, I must reference the table’s context explicitly (as in h below), even if the function were defined in the table’s context.
q)a:2 q)\d .ex q.ex)a:3 q.ex)f:{get[`a]+1} q.ex)g:{a+1}
q.ex)h:{get[`.ex.a]+1} q.ex)f 4 q.ex)g 4
q.ex)h
4 q.ex)\d . q).ex.f 3 q).ex.g 4
q).ex.h
4
It’s not that big a deal, but the reason I wanted to avoid specifying the context in the function is for code reuse. For example, if I wanted to run a script originally written to use the .ex context using the default context, I would need to modify every function that references a global table by name.
Thanks,
Rob
29.11.2016, 12:02, “RAHUL ASATI” <rahul.asati04@gmail.com>:
Which version are you using? If you run that from .ex context that should work. Its working for me.
Another behavior to note is that variables referenced using backtick inside function are parsed as constants (use value on function to get details) and constants are read/write in the context in which function is executing.
Ex:
q) a:2 // root context
q) \d .ex
q.ex) a: 3 // .ex context
q.ex) f:{get[`a]+1}
q.ex) f // output - 4 (read from .e context)
q.ex)\d .
q) .ex.f // output - 3 read from root context
Above behavior also applies to tables with backticks (ex: when used in insert/upsert commands). So make sure that function is getting executed in correct context as that could corrupt data in other workspace if there is a table with same name(and schema).
On Tuesday, 29 November 2016 05:52:01 UTC, Rob Smith wrote:
Thanks. So is there any way to modify a table in a non-default context using its unqualified name? For example, say I have two tables and a function defined in the .ex context: \d .ex asks:bids:(buy:0#1b; id:0#0Ng; px:0#0n; qty:0#0n) addOrder:{$[x`buy;`bids;`asks]upsert x} When I run addOrder `buy`id`px`qty!(1b;rand 0Ng;12.34;100f) the order isn’t upserted into .ex.bids. Even though the function is defined in the .ex context, bids is modified in the default context.
28.11.2016, 15:03, “RAHUL ASATI” <rahul…@gmail.com>:
Look at this as link as well- http://code.kx.com/wiki/JB:QforMortals/workspace_organization#Functions_and_Contexts
It has some good examples.
From the link - “The context of an unqualfied global variable in a function is the context in which the function is defined, not the context in which it is evaluated.”
On Monday, 28 November 2016 11:35:54 UTC, Rob Smith wrote:
Perfect. Thanks!
28.11.2016, 10:54, “Sean O’Hagan” <soh…@firstderivatives.com>:
You can have a look at the internals of the function:
http://code.kx.com/wiki/Reference/value
(at the valuing of a function part)You can see the differences at the (context;globals) part of the result with this quick approach:
cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]
cont glob .a.f a g .b.f g Telling you .b.f is looking for g in the root context and hence your error.
HTH,
SeanOn Monday, November 28, 2016 at 10:12:47 AM UTC, Rob Smith wrote:
I can create two namespaces, .a and .b:
q)\d .a
q.a)f:{g}
q.a)g:{showhello} q.a)\d . q).b.f:{g[]} q).b.g:{show
hello}The namespaces appear to be identical, but internally they’re not:
q).Q.s1[.a]~.Q.s1 .b
1b
q).a~.b
0bAnd when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:
q).a.f
`hello
q).b.f
{g}
'gWhy the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?
Thanks,
Rob
–
Submitted via Google Groups
Sorry, the formatting of my example got screwed up:q)a:2q)\d .exq.ex)a:3q.ex)f:{get[a]+1}q.ex)g:{a+1}q.ex)h:{get[
.ex.a]+1}q.ex)f4q.ex)g4q.ex)h4q.ex)\d .q).ex.f3q).ex.g4q).ex.h429.11.2016, 12:38, “Rob Smith” :> I’m using 3.4 and can reproduce your example, so I don’t think it’s a bug.>> I was expecting f to return the same result regardless of from what context it was called. When using a variable directly, as in g below, the context used for variable lookups is always that in which the function was defined. But I guess that is not possible when using a variable by referencing its symbol name.>> So if I want to modify a table defined in a non-default context using a function that may be called from another context, I must reference the table’s context explicitly (as in h below), even if the function were defined in the table’s context.>> q)a:2 q)\d .ex q.ex)a:3 q.ex)f:{get[a]+1} q.ex)g:{a+1}> q.ex)h:{get[
.ex.a]+1} q.ex)f 4 q.ex)g 4> q.ex)h> 4 q.ex)\d . q).ex.f 3 q).ex.g 4> q).ex.h> 4>> It’s not that big a deal, but the reason I wanted to avoid specifying the context in the function is for code reuse. For example, if I wanted to run a script originally written to use the .ex context using the default context, I would need to modify every function that references a global table by name.>> Thanks,> Rob>> 29.11.2016, 12:02, “RAHUL ASATI” <rahul.asati04>:>> Which version are you using? If you run that from .ex context that should work. Its working for me.>>>> Another behavior to note is that variables referenced using backtick inside function are parsed as constants (use value on function to get details) and constants are read/write in the context in which function is executing.>>>> Ex:>>>> q) a:2 // root context>> q) \d .ex>> q.ex) a: 3 // .ex context>> q.ex) f:{get[a]+1}>> q.ex) f[] // output - 4 (read from .e context)>> q.ex)\d .>> q) .ex.f[] // output - 3 read from root context>>>> Above behavior also applies to tables with backticks (ex: when used in insert/upsert commands). So make sure that function is getting executed in correct context as that could corrupt data in other workspace if there is a table with same name(and schema).>>>> On Tuesday, 29 November 2016 05:52:01 UTC, Rob Smith wrote:>>> Thanks. So is there any way to modify a table in a non-default context using its unqualified name? For example, say I have two tables and a function defined in the .ex context: \d .ex asks:bids:([]buy:0#1b; id:0#0Ng; px:0#0n; qty:0#0n) addOrder:{$[x
buy;bids;
asks]upsert x} When I run addOrder buy
idpx
qty!(1b;rand 0Ng;12.34;100f) the order isn’t upserted into .ex.bids. Even though the function is defined in the .ex context, bids is modified in the default context.>>>>>> 28.11.2016, 15:03, “RAHUL ASATI” <rahul…>:>>>> Look at this as link as well- http://code.kx.com/wiki/JB:QforMortals/workspace_organization#Functions_and_Contexts>>>>>>>> It has some good examples.>>>>>>>> From the link - “The context of an unqualfied global variable in a function is the context in which the function is defined, not the context in which it is evaluated.”>>>>>>>> On Monday, 28 November 2016 11:35:54 UTC, Rob Smith wrote:>>>>> Perfect. Thanks!>>>>>>>>>> 28.11.2016, 10:54, “Sean O’Hagan” <soh…>:>>>>>> You can have a look at the internals of the function:>>>>>>>>>>>> http://code.kx.com/wiki/Reference/value>>>>>> (at the valuing of a function part)>>>>>>>>>>>> You can see the differences at the (context;globals) part of the result with this quick approach:>>>>>>>>>>>> cont
glob!/:l!raze each r[;where not (~'). r:(get get@)each l:.a.f
.b.f]>>>>>> | cont glob>>>>>> ----| --------->>>>>> .a.f| a g>>>>>> .b.f| g>>>>>>>>>>>> Telling you .b.f is looking for g in the root context and hence your error.>>>>>>>>>>>> HTH,>>>>>> Sean>>>>>>>>>>>> On Monday, November 28, 2016 at 10:12:47 AM UTC, Rob Smith wrote:>>>>>>> I can create two namespaces, .a and .b:>>>>>>>>>>>>>> q)\d .a>>>>>>> q.a)f:{g}>>>>>>> q.a)g:{showhello}>>>>>>> q.a)\d .>>>>>>> q).b.f:{g[]}>>>>>>> q).b.g:{show
hello}>>>>>>>>>>>>>> The namespaces appear to be identical, but internally they’re not:>>>>>>>>>>>>>> q).Q.s1[.a]~.Q.s1 .b>>>>>>> 1b>>>>>>> q).a~.b>>>>>>> 0b>>>>>>>>>>>>>> And when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:>>>>>>>>>>>>>> q).a.f>>>>>>> `hello>>>>>>> q).b.f>>>>>>> {g}>>>>>>> 'g>>>>>>>>>>>>>> Why the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?>>>>>>>>>>>>>> Thanks,>>>>>>> Rob>>>>>>>>>>>> –>>>>>>
Submitted via Google Groups</soh…></rahul…></rahul.asati04>
Ok, last post on this topic..Nick suggested not storing data in namespaces, which seems like an unfortunate sacrifice, but I can work around that. But now I’m seeing that even functions don’t seem to work well when defined in a namespace. For example:q)\d .nsq.ns)rnd2:{(“j”$100f*x)%100f}eachq.ns)f:{update qty:rnd2 qty+1f from (qty:1?1f)}q.ns)\d .q).ns.f{update qty:rnd2 qty+1f from (qty:10?1f)}‘rnd2I’m unable to use the rnd2 function in a select/update statement because internally kdb is looking up the function by name which looks for it in the calling context rather than the function’s definition context.Am I not using namespaces as they were intended? They don’t seem to be useful beyond trivial use cases. Is there a better approach to creating self-contained units of code/data when running everything in a single process?29.11.2016, 12:46, “Rob Smith” :> Sorry, the formatting of my example got screwed up:>> q)a:2> q)\d .ex> q.ex)a:3> q.ex)f:{get[a]+1}> q.ex)g:{a+1}> q.ex)h:{get[
.ex.a]+1}> q.ex)f> 4> q.ex)g> 4> q.ex)h> 4> q.ex)\d .> q).ex.f> 3> q).ex.g> 4> q).ex.h> 4>> 29.11.2016, 12:38, “Rob Smith” :>> I’m using 3.4 and can reproduce your example, so I don’t think it’s a bug.>>>> I was expecting f to return the same result regardless of from what context it was called. When using a variable directly, as in g below, the context used for variable lookups is always that in which the function was defined. But I guess that is not possible when using a variable by referencing its symbol name.>>>> So if I want to modify a table defined in a non-default context using a function that may be called from another context, I must reference the table’s context explicitly (as in h below), even if the function were defined in the table’s context.>>>> q)a:2 q)\d .ex q.ex)a:3 q.ex)f:{get[a]+1} q.ex)g:{a+1}>> q.ex)h:{get[
.ex.a]+1} q.ex)f 4 q.ex)g 4>> q.ex)h>> 4 q.ex)\d . q).ex.f 3 q).ex.g 4>> q).ex.h>> 4>>>> It’s not that big a deal, but the reason I wanted to avoid specifying the context in the function is for code reuse. For example, if I wanted to run a script originally written to use the .ex context using the default context, I would need to modify every function that references a global table by name.>>>> Thanks,>> Rob>>>> 29.11.2016, 12:02, “RAHUL ASATI” <rahul.asati04>:>>> Which version are you using? If you run that from .ex context that should work. Its working for me.>>>>>> Another behavior to note is that variables referenced using backtick inside function are parsed as constants (use value on function to get details) and constants are read/write in the context in which function is executing.>>>>>> Ex:>>>>>> q) a:2 // root context>>> q) \d .ex>>> q.ex) a: 3 // .ex context>>> q.ex) f:{get[a]+1}>>> q.ex) f[] // output - 4 (read from .e context)>>> q.ex)\d .>>> q) .ex.f[] // output - 3 read from root context>>>>>> Above behavior also applies to tables with backticks (ex: when used in insert/upsert commands). So make sure that function is getting executed in correct context as that could corrupt data in other workspace if there is a table with same name(and schema).>>>>>> On Tuesday, 29 November 2016 05:52:01 UTC, Rob Smith wrote:>>>> Thanks. So is there any way to modify a table in a non-default context using its unqualified name? For example, say I have two tables and a function defined in the .ex context: \d .ex asks:bids:([]buy:0#1b; id:0#0Ng; px:0#0n; qty:0#0n) addOrder:{$[x
buy;bids;
asks]upsert x} When I run addOrder buy
idpx
qty!(1b;rand 0Ng;12.34;100f) the order isn’t upserted into .ex.bids. Even though the function is defined in the .ex context, bids is modified in the default context.>>>>>>>> 28.11.2016, 15:03, “RAHUL ASATI” <rahul…>:>>>>> Look at this as link as well- http://code.kx.com/wiki/JB:QforMortals/workspace_organization#Functions_and_Contexts>>>>>>>>>> It has some good examples.>>>>>>>>>> From the link - “The context of an unqualfied global variable in a function is the context in which the function is defined, not the context in which it is evaluated.”>>>>>>>>>> On Monday, 28 November 2016 11:35:54 UTC, Rob Smith wrote:>>>>>> Perfect. Thanks!>>>>>>>>>>>> 28.11.2016, 10:54, “Sean O’Hagan” <soh…>:>>>>>>> You can have a look at the internals of the function:>>>>>>>>>>>>>> http://code.kx.com/wiki/Reference/value>>>>>>> (at the valuing of a function part)>>>>>>>>>>>>>> You can see the differences at the (context;globals) part of the result with this quick approach:>>>>>>>>>>>>>> cont
glob!/:l!raze each r[;where not (~’). r:(get get@)each l:.a.f
.b.f]>>>>>>> | cont glob>>>>>>> ----| --------->>>>>>> .a.f| a g>>>>>>> .b.f| g>>>>>>>>>>>>>> Telling you .b.f is looking for g in the root context and hence your error.>>>>>>>>>>>>>> HTH,>>>>>>> Sean>>>>>>>>>>>>>> On Monday, November 28, 2016 at 10:12:47 AM UTC, Rob Smith wrote:>>>>>>>> I can create two namespaces, .a and .b:>>>>>>>>>>>>>>>> q)\d .a>>>>>>>> q.a)f:{g}>>>>>>>> q.a)g:{showhello}>>>>>>>> q.a)\d .>>>>>>>> q).b.f:{g[]}>>>>>>>> q).b.g:{show
hello}>>>>>>>>>>>>>>>> The namespaces appear to be identical, but internally they’re not:>>>>>>>>>>>>>>>> q).Q.s1[.a]~.Q.s1 .b>>>>>>>> 1b>>>>>>>> q).a~.b>>>>>>>> 0b>>>>>>>>>>>>>>>> And when I call .a.f, it knows to look for g in the .a namespace, but .b.f tries to find g in the global namespace:>>>>>>>>>>>>>>>> q).a.f>>>>>>>> `hello>>>>>>>> q).b.f>>>>>>>> {g}>>>>>>>> 'g>>>>>>>>>>>>>>>> Why the difference? Is there any way to distinguish between the two behaviors (other than knowing how the namespaces were created)?>>>>>>>>>>>>>>>> Thanks,>>>>>>>> Rob>>>>>>>>>>>>>> –>>>>>>>
Submitted via Google Groups</soh…></rahul…></rahul.asati04>
Hi Rob,
For your first example - there are workarounds(do not forget nick’s notes though)
.e.g
\d .ex
asks:bids:([]buy:0#1b; id:0#0Ng; px:0#0n; qty:0#0n)
addOrder:{(` sv `,get[.z.s][3;0],$[x`buy;`bids;`asks])upsert x}
\d .
//now below will upsert to .ex.bids as you require
.ex.addOrder`buy`id`px`qty!(1b;rand 0Ng;12.34;100f)
for your last example you should read about masking here http://code.kx.com/wiki/Reference/select#scope
and again use ‘value’ to your advantage..shown below
\d .ns
rnd2:{(“j”$100f*x)%100f}each
f:{update qty:rnd2 qty+1f from (qty:1?1f)}
f2:{{update qty:x qty+1f from (qty:1?1f)}rnd2}
\d .
.ns.f
{update qty:rnd2 qty+1f from (qty:1?1f)}
'rnd2
\
.ns.f2
qty
1.58
//use value to see what’s going on…
l!.[;(::;3)]get each .ns l:f
f2
f | ,ns f2|
ns`rnd2
HTH,
Sean
using q-sql adds a convenient syntax, but is not always necessary.
best practices would dictate that your namespace should have utility functions that apply to generic data with no knowledge of table column names. this would allow anyone to use your library regardless of how they decide to name their columns.
the tables should also be passed in as arguments so the user can use them on stack variables within functions.
agreed that there are limitations on how namespace are managed, but i’ve rarely found this to be a problem. if you read the code from Q Tips, you will see that functions are used across namespaces without issue.
note you can generalize your code a bit by making a rnd function
rnd:{x*“j”$y%x}
rnd2:rnd[.01]
also note that q is a vector language and that there is no need to use ‘each’ in your example above.