Struggling to understand two statements

I am studying the official example code from here: https://github.com/kxcontrib/websocket/blob/master/AppendixB/pubsub.q and after thinking for a while I still don’t understand what exactly a few lines do:

 

 

 

trade:flip timesympricesize!“nsfi”$:(); subs:2!flip handlefunc`params!“is*”$:();

 

 

 

The following is the things I already know:

  1. Q generally read from right to left;
  2. We assign the results to trade/subs;
  3. flip is used to transpose an input
  4. time sym are “symbols”
  5. “nsfi” is used to specify the type of columns

Then here comes the things I don’t know…

  1. What does $:() do?
  2. How about the bang between symbols and “nsfi”?
  3. What does 2!flip mean?..

 

Thanks!

  1. : represents each left and $ is casting.

https://code.kx.com/q/ref/maps/#each-left-and-each-right

https://code.kx.com/q4m3/7_Transforming_Data/#72-cast 

So for the line “nsfi”$:() it is actually casting an empty list with every type on the left (hence each left) so that it creates a list of that specific type. You can use .Q.s1 to view the string representation of the object.

https://code.kx.com/q/ref/dotq/#qs1-string-representation 

q)“n”$() timespan$() q).Q.s1 "nsfi"$\:() "(timespan$();symbol$();float$();`int$())"

  1. bang (!) is used to create a dictionay with the keys on the left and values on the right with the correct length of list. Then flipping a dict will turn it into a tbl.

https://code.kx.com/q/ref/dict/ 

https://code.kx.com/q/kb/faq/#flip-a-column-dictionary 

  1. 2! enkeys the table by the first 2 cols.

https://code.kx.com/q/ref/enkey/ 

Hope this helps!

Hi mauricelim, thanks for the quick help! Can I say that the big picture is to define two empty tables called trade and subs here? 

Yes, it is creating a table schema of specific type for the cols. So when you are manipulating the table, it throws a type error if the type is not of that defined in the schema.

https://code.kx.com/q/ref/insert/#type 

More information here: https://code.kx.com/q4m3/8_Tables/#82-empty-tables-and-schema 

The [q Reference](“https://code.kx.com/q/ref/” "“q”) aims to answer questions such as yours and I am always looking for ways to improve it.

Did you look there for answers? If so, I would be very grateful for anything you can tell me about what worked and how far you were able to get with your three questions before getting stuck. 

Best

Stephen, KX Librarian

Hi @SJT, actually I did try finding answers from Refererence card (https://code.kx.com/q/ref/) as well as Overloaded glyphs (https://code.kx.com/q/ref/overloads/)"). For some simpler questions, I can find solutions directly from them. However, I think the combination is a bit too complicated for a beginner like myself and I failed to understand what exactly the statements are about even after looking into these two pages…

I wonder… did you try evaluating parts of the expression? E.g. 

q)“is*”$:() q)handlefuncparams!"is*"$\:() handle| func | params| q)flip handlefuncparams!“is*”$:() handle func params ------------------ q)2!flip handlefunc`params!“is*”$:() handle func| params -----------| ------

I can see this might have required some experimenting to find which parts of the expression are themselves valid expressions. A text editor with q syntax highlighting (I use Sublime Text) might be helpful here.

What would it helped to have looked up but could not? 

lol but think about it…you know how to evaluate “parts” of the expression because you already know which characters are one “part”. For me (well at least the me a few days ago), it is like this:

helloworld*&*(&(ASYD*(&63qe!~!#().

I dont even know how many parts are there…