Pattern match syntax

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:initelection!({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

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