alternatives to custom notations

Pattern matching of general data structures is an elegant and powerful programming technique, that is being used since a long time in (mostly) research programming languages such as ML, Prolog, Erlang, and many others. In spite of the clear advantages of pattern matching, this technology still hasn't reached mainstream languages, used by the vast majority of programmers, not even the most recent languages such as Java, JavaScript, or C#.

There are however some well-known technologies that achieve some effects similar to the pattern matching offered by myPatterns. These are briefly discussed here.

regular expressions

Pattern matching of strings, using regular expressions, is readily available in all mainstream languages, either within the language or as a library. Regular expressions are very useful when manipulating text, but they are not applicable to programs using general data structures such as lists, arrays, or objects. Stringifying a data structure and matching it with regular expressions is not nearly enough, because regular expressions are fundamenatlly limited in that they do not cover (recursively) nested constructs (such as data structures).
For instance, say you want to match a Person object of the form {... age: 18 ...}. There is no way using regular expressions to do this in all cases. For instance, the regular expression /{.* age:([0-9]*).*}/ works just fine for the object {name: "Bill", age: 18}, but not for the object:
{name: "Bill", father: {name: "Ben", age: 49}, age: 18, friend: {name: "Bob", age:16}}
for which it will match either the age of Bill's father or Bill's friend (depending whether you are using shortest match or longest match), instead of matching Bill's age. This is because regular expressions cannot express something like "any substring containing well-nested braces".
In turn, myPatterns allows you to simply write "{age: 18}" for matching exactly the intended objects. On the other hand myPatterns include support for regular expression matching. For instance, the pattern "{author:/^(.*)ski$/}" matches any (say) book written by an author whose name ends in "ski", and returns the stem of that name.

XPath

Matching of XML documents using pattern (and query) languages such as XPath or XQuery is available in all mainstream languages, either within the language (e.g. the E4X extension in JavaScript) or as a library. XPath-style matching is very useful when manipulating XML data or HTML documents, but is of no help when manipulating user-defined or system-defined data structures used everywhere in most programs, that do not come from parsing an XML source. Although there is a recent trend for technologies allowing to see data structures as XML, and thereby allowing to use XPath-style matching for general data structures, XPath notations are much more verbose and cumbersome compared to notations specifically designed for lists, terms, etc.
For example, consider the following native JavaScript object:
var john = 
{name: {firstname: "John", lastname: "Smith"}, 
 children:[{firstname: "Eric", gender: "male", born: 1991}, 
           {firstname: "Deborah", gender: "female", born: 1996}]};
and say you want to check if the first kid of this person is 18, and at the same time get the father's name and the list of brothers/sisters of the teenager. When using myPatterns/JS, this is done very simply as a single test, using a JSON pattern complemented by a boolean expression:
(s = match(x, "{name:{lastname: %l}, children:[{gender: 'male', born: %b} | %x]}")) 
&& new Date().getFullYear() - s.b == 18
In turn, for using XPath on this data, the solution is much more elaborate, involving converting the data to XML (for example the XML type of E4X), via an XML serialization using some O/X mapper (for example OBJtree):
// Convert john from JSON to XML string
var xotree = new XML.ObjTree();
xotree.xmlDecl = '';
var johnxs = xotree.writeXML( john );

// Parse back XML string as E4X
johnx = new XML("" + johnxs + "");

// Extract subdata as variables
var l = johnx.name.lastname;
var b = johnx.children[0].born;
var x = new Array();
for(var i = 1; i < johnx.children.length(); i++)
  x.push(johnx.children[i]);

// Compute the result of matching
johnx.children[0].gender == "male"
&& new Date().getFullYear() - b == 18;
Note: if you are aware of a simpler solution than that, please let us know.

Other than being so verbose, this solution is also very inefficient, as it requires to serialize completely the data, that may be huge. In constrast, myPatterns only traverses the data as needed by the pattern. There is also the problem of circular data, that makes OBJTree hang, while myPatterns handles such data just fine.

Finally, even if all these issues are solved, myPatterns brings you the comfort and conciseness of a "concrete syntax" notation, allowing to both recognize and decompose data declaratively, in a single step. In this example, the notation was JSON-like. Furthermore and most importantly, myPatterns lets you redefine new notations as you wish, if JSON is not adequate for your specific data or application.

XLST

XLST is a general-purpose XML to XML transformer that also includes XPath as a query language. The relation between concrete syntax patterns and XPath patterns has been discussed above. Beyond this difference, the main difference between XSLT itself and myPatterns is that the former is working on external XML data while the latter is working on native data structures.

However, there are some scenarios where either one of the two technologies could be used, for example when extracting data into a HTML table.

The following myPatterns/JS query extracts information from a table of Person objects like the one above:

tableMatching(persons, "{name:{lastname:%l, firstname:%f}, [{born: %x}, {born:%y}]}");
into an HTML table such as the following:

lfxy
SmithJohn19911996
JohnsonMatt19781979

Of course, such an HTML table can be also generated very naturally using XSLT from persons information (supposing the data were stored in an XML file), but the XLST stylesheet is considerably more verbose.

LINQ

See myPatterns & LINQ.

JSONPath & JSONQuery

See myPatterns & JSONQuery.

language pre-processors

Matching in convenient concrete syntaxes of general data structures such as objects is now available using non-standard extensions of mainstream languages, such as Java pre-processors (for example, JMatch). These technologies provide effective pattern matching solutions, but require programmers to adopt non-standard tools, thereby endorsing the associated risks, among which: incompatibility with the rest of the world, non-optimal debugging support, etc.
As opposed to that, custom notations are a technology for pattern matching of general data structures that can be used in mainstream languages such as C and JavaScript, without changing anything to the development environment. Programmers may continue using their favorite compiler or interpreter, debugger, IDE, etc. They only have to include in their application the myPatterns library -- a minimal, free, open source library.

But custom notations go far beyond providing pattern matching features for data structures. As their name suggests, the custom notations technology allows programmers defining their own notations for data structures, to be used in patterns.

conclusion

myPatterns/JS is not meant to replace technologies such as regular expressions, XPath, or LINQ, but rather complement them by offering pattern matching of native data structures in the concrete syntax of your choice.
Last updated on: 30/5/2010 Contact us