simulating class behavior

I need some way to simulate class behaviour in q

Something I can call like this

d: .dictBuilder.new[];d.put[y;13];d.put[hjk; ("a";"b";"c")];res: d.build[];show resx| 1y| 13h| "a"j| "b"k| "c"

So I came up with this idea

  1. store class instance in a namespace dict and keyed by instance id. new dict entry will be added every time new is called 

For example, dict3 and dict4 are two instances created in memory

show .dictBuildermax_instance_id | 4dict3 | ``y!(();13)dict4 | ``hjk!(();"a";"b";"c")

  1. use function projection with instance id to simulate method call on instance (note projection with dict3]) .dictBuilder.put: {[instance_id;k;v] $[0 > type k; .dictBuilder[instance_id],:(enlist k)! enlist v; .dictBuilder[instance_id],:(k)! v]; };.dictBuilder.build: {[instance_id; dummy] r: .dictBuilder[instance_id]; .dictBuilder: instance_id _ .dictBuilder; //remove instance after it was built r: _ r; //remove null key r};

  2. instance id is generated and bind to instance method at creation

.dictBuilder.new:{ if[not dictBuilder in key ; .dictBuilder.max_instance_id: -1]; //create new namespace if not exist instance_id: $“d”,string .dictBuilder.max_instance_id+:1; //assign new instance id .dictBuilder[instance_id]: (enlist)!enlist(); //create new instance builder: (enlist)!enlist(); builder[instance_id]: instance_id; builder[put]: .dictBuilder.put[instance_id]; builder[build]: .dictBuilder.build[instance_id]; builder};

  1. done. you can call it like above code

Does anyone have other solution for this? Are you aware of any problem with this approach?

The reason why I came up with this idea is simply because I was looking for a cleaner way to do this

To create generic dict, this wouldn’t work

d: ()!();d[x]: 1;d[`y]: “f”`type`
So I had to do this. 

d: (enlist)!enlist();d[x]: 1;d[y]: “f”; _ d

Hi Komsit

What’s the problem you are trying to solve?  I’m not sure if simulating classes makes a lot of sense in kdb+ - might be better to rethink it.  One thing that may work would be to just use a keyed table - so the “class definition” is the table structure, and each row of the table is an instance of the class.  You would have a bit of overhead (as null/empty values would have to be stored) but it would be easier. 

The other approach using dictionaries, if you really don’t like the null value in the key, is just to enlist everything as you put it in e.g. 

q)d:()!()

q)d[`x]:enlist 1                                                                                                                                                                                           

q)d[`y]:enlist “A”                                                                                                                                                                                         

q)d[`z]:enlist “ABC”                                                                                                                                                                                       

q)d                                                                                                                                                                                                        

x| 1    

y| A    

z| “ABC”

Thanks 

Jonny

Hi Jonny,

Yeah, that’s probably a bad idea lol

The null dict key is just a small problem that I had, and it seems to be overkill to try to simulate the class  to solve it. And your solution looks good.

What I’m interest in general is, if anyone has tried to create a class-like data structure in q. I imagine it would be helpful if we can use class in q. But maybe I’m not thinking in q way.

Actually Jonny, this doesn’t exactly work for me

d[`x]:enlist 1  <– then I’ll get list of 1 instead of 1i

Yes, you have to un-enlist it (use first) when you get it out. 

Or just live with the null key. 

Thanks 

Jonny 

Andrey did something similar in the past:<o:p></o:p>

<o:p> </o:p>

http://code.kx.com/wsvn/code/contrib/azholos/oop.q<o:p></o:p>

<o:p> </o:p>

And yes if possible please avoid oop in kdb. <o:p></o:p>

<o:p> </o:p>

Kim<o:p></o:p>

<o:p> </o:p>

Von: personal-kdbplus@googlegroups.com [mailto:personal-kdbplus@googlegroups.com] Im Auftrag von Komsit Prakobphol
Gesendet: Dienstag, 3. November 2015 14:57
An: Kdb+ Personal Developers
Betreff: [personal kdb+] simulating class behavior<o:p></o:p>

<o:p> </o:p>

I need some way to simulate class behaviour in q<o:p></o:p>

<o:p> </o:p>

Something I can call like this<o:p></o:p>

d: .dictBuilder.new;<o:p></o:p>

d.put[`y;13];<o:p></o:p>

d.put[`h`j`k; (“a”;“b”;“c”)];<o:p></o:p>

res: d.build;<o:p></o:p>

show res<o:p></o:p>

x| 1<o:p></o:p>

y| 13<o:p></o:p>

h| “a”<o:p></o:p>

j| “b”<o:p></o:p>

k| “c”<o:p></o:p>

<o:p> </o:p>

So I came up with this idea<o:p></o:p>

  1. store class instance in a namespace dict and keyed by instance id. new dict entry will be added every time new is called <o:p></o:p>

For example, dict3 and dict4 are two instances created in memory<o:p></o:p>

show .dictBuilder
max_instance_id | 4<o:p></o:p>

dict3           | ``y!(();13)<o:p></o:p>

dict4           | ``hjk!(();“a”;“b”;“c”)<o:p></o:p>

  1. use function projection with instance id to simulate method call on instance (note projection with `dict3])<o:p></o:p>

.dictBuilder.put: {[instance_id;k;v] <o:p></o:p>

      $[0 > type k;<o:p></o:p>

            .dictBuilder[instance_id],:(enlist k)! enlist v;<o:p></o:p>

            .dictBuilder[instance_id],:(k)! v];<o:p></o:p>

      };<o:p></o:p>

.dictBuilder.build: {[instance_id; dummy] <o:p></o:p>

      r: .dictBuilder[instance_id];<o:p></o:p>

      .dictBuilder: instance_id _ .dictBuilder; //remove instance after it was built<o:p></o:p>

      r: ` _ r;        //remove null key<o:p></o:p>

      r};                           <o:p></o:p>

<o:p> </o:p>

  1. instance id is generated and bind to instance method at creation<o:p></o:p>

.dictBuilder.new:{<o:p></o:p>

      if[not dictBuilder in key ; .dictBuilder.max_instance_id: -1]; //create new namespace if not exist<o:p></o:p>

      instance_id: `$“d”,string .dictBuilder.max_instance_id+:1;       //assign new instance id<o:p></o:p>

      .dictBuilder[instance_id]: (enlist`)!enlist();                   //create new instance<o:p></o:p>

<o:p> </o:p>

      builder: (enlist`)!enlist();<o:p></o:p>

      builder[`instance_id]: instance_id;<o:p></o:p>

      builder[`put]: .dictBuilder.put[instance_id];<o:p></o:p>

      builder[`build]: .dictBuilder.build[instance_id];<o:p></o:p>

      builder};<o:p></o:p>

  1. done. you can call it like above code<o:p></o:p>

<o:p> </o:p>

Does anyone have other solution for this? Are you aware of any problem with this approach?<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

The reason why I came up with this idea is simply because I was looking for a cleaner way to do this<o:p></o:p>

To create generic dict, this wouldn’t work<o:p></o:p>

d: ()!();<o:p></o:p>

d[`x]: 1;<o:p></o:p>

d[y]: "f" type<o:p></o:p>

So I had to do this. <o:p></o:p>

d: (enlist`)!enlist();<o:p></o:p>

d[`x]: 1;<o:p></o:p>

d[`y]: “f”;<o:p></o:p>

` _ d<o:p></o:p>

<o:p></o:p>


Submitted via Google Groups

Hi Kim,

Thanks for the link! That is interesting.

Komsit

Hi Komsit,

I created two versions of oop for Q just to see how it looks. One is java-like and the second follows lisp CLOS.

The Java like lib allows you to create objects with new, access their state like obj[fn;arg1;..] or obj[field] and etc.Obj is a ‘general function’  that calls the correct function based on its args. Contructors, inheritance. get/set are supported. GC can delete objects automatically. The class definition looks like:

.oo.class[cron.job;()] &nbsp;((..abstract;1);
  (Name;none);
  (sTime;-0wp);(eTime;0wp);(interval;0D01); &nbsp; (.cron;undef);(Status;off);(Lastval;::);
  (;cron.job;.oo.setcnstr.cronName);
  (;start;{[th] if[off=thStatus; if[-16=type t:thsTime; th[sTime;.z.P+t]]; if[-16=type t:theTime; th[eTime;.z.P+t]]; th[.cron][add;th[Status;on]]]; ththis}); &nbsp; (;stop;{[th] th[.cron][delete;th[Status;off]]; ththis});
  (;next;{[TH;prv] if[off=THStatus; :0np]; $[null prv;min(max(THsTime;.z.P);THeTime);null THinterval;0np;prv=THeTime;0np;min(.z.P+THinterval;THeTime)]});
  (;run;{[th] }));

.oo.class[cron.job.periodic;cron.job]
 ((args;::);(fn;{});
  (;cron.job.periodic;.oo.setcnstr.cronNamefn); &nbsp; (;run;{[th] th[Lastval;v:.[thfn;(),thargs;{"Failed with: ",x}]]; v}));

I’ve found that class definitions look very messy though this can be useful for some libraries when you need to manage individual state a lot.

CLOS lib allows you create generic functions that call specific functions based on types and/or values of its args like fn[a;10] vs fn[10;a]. It supports type hierarchy (list -> table) and Java OOP classes.

If you are interested I can add this lib to contrib svn.

WBR, Andrey Kozyrev.

???, 5 ??? 2015 ?., 15:53:27 UTC+3 ??? Komsit Prakobphol ???:

Hi Kim,

Thanks for the link! That is interesting.

Komsit

Hi Andrey - cool, are you using this in any production system? yes, please add to svn. I am interested! thanks!!
Komsit

Hi Komsit,

You can find it here http://code.kx.com/wsvn/code/contrib/akozyrev/lib/

oop.q is the main file, oolib are some examples (messy).

The basic usage:

.oo.class[myClass;();((a;10);(;myClass;{[th;x] th[a;x]});(;printA;{[TH] -1 "My val: ",string THa;}))]

q)a`a
100

q)a`printA
My val: 100

q)a[`a;+;10]

q)a`printA
My val: 110

.oo.class[myLine;myClass;((b;10);(;myLine;{[th;x;y] th[a;x]; th[b;y]});(;printA;{[th] th[myClass:printA]; -1 "My second val: ",string thb;});(;getPoint;{[th;x] th[b]+th[`a]*x}))]

q)l:.oo.new[myLine;10;20] q)lprintA
My val: 10
My second val: 20

q)l[`getPoint;10]
120

/ gc can collect unreferenced objects

q)a:l:0

q).oo.gc
2

th is like a pointer to the object, TH is the underlying dictionary (works faster but you can’t call functions).

WBR, Andrey.

Great, Thank you!