cancel
Showing results for 
Search instead for 
Did you mean: 

Pattern match syntax

robmoore121
New Contributor
Hi,

Say I am a process who is capable of receiving various types of dictionary messages. The contents of the messages are marked by appending a tag key to the dictionary, whose value is the marker on the message. For example, a process might accept an `init tag for arguments it expects to be sent shortly after being spawned. It may later accept an `election tag to indicate that a message contains information regarding some leadership election execution.

It is of course easy to perform pattern matching using a dictionary, for example:

matcher:`init`election!({function 1};{function2})
function:matcher@(m`tag)
function m

However, the syntax isn't especially nice. As the number of keys grows, it becomes harder to immediately tell which key matches which function.

A possible solution is to use table syntax to clearly indicate the mapping:

([]
  init:enlist {function1};
  election:enlist {function2})

It is definitely an improvement, but the enlists are kind of an eyesore.

Is there a cleaner way to build key-value stores where the mapping can be immediately seen in the code? Has anyone experimented with functions to do stuff like this? I have built a match[dictionary;key;mapping] function for the table syntax, and it's tolerable, but I'm interested in seeing if other people have got any nicer solutions, perhaps even a reframing of the initial problem that leads to a more elegant solution?

Rob
2 REPLIES 2

James_Burrows
New Contributor
Hi Rob,

There are a few different ways of writing your code that will make it immediately clear how it is mapped. 
To set it up in a dictionary you can use:

   dict:(!/) flip 2 cut(`name1;`func1;`name2;`func2)

To call the relevant function you can use:

      dict`name1


Another way of going about this would be to use a mapper function as seen below. Calling the functions from within the dictionary can be done similarly to above.
   
      mapper:()!()
      mapper[`name1]:`func1
      mapper[`name2];`func2


Or define this as a namespace:

      .mapper.name1:func1;
      .mapper.name2:func2;
 
(A namespace is like a dictionary, except its first value is a generic null (::))

Which you could then wrap in a function so that each message received indexes into the namespace:

      {[msg] .mapper[msg`tag]msg}

The kx wiki has more information on namespaces:
http://code.kx.com/q4m3/12_Workspace_Organization/#121-namespaces

Hope this helps,
James

Hi James,

Those are really nice solutions, I especially like the first one. Thank you!

Rob