npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

junify

v1.0.2

Published

JavaScript implementation of the unification algorithm

Downloads

51

Readme

JUnify ― JavaScript Unification Library

JUnify is a JavaScript library for performing unification on objects and arrays. It can be executed by any browser that supports JavaScript version 1.5 and Node.js. Unification is an algorithm to determine the substitutions needed to make two expressions match. If the expressions contain variables, these will need to be bound to values in order for the match to succeed. If two expressions are not identical or the variables can not be bound, the match fails. In the following example unification is used to extract values from a JSON object using an pattern object:

var point = {
    coords: [12, 10, 80], 
    color:  [255, 0, 0]
};

var pattern = {
    coords: [variable('x'), variable('y'), _], 
    color:  variable('color')
};

// a.x = 12, a.y = 10, a.color = [255, 0, 0]
var a = unify(pattern, point);

The syntax and use-case in this example is similar to destructuring assignment in JavaScript 1.7. Its use is however not limited to extracting fields. Unification can, for example, also be used to implement pattern matching or an expert system (Artificial Intelligence, Structures and Strategies for Complex Problem Solving, by George F. Luger. Addison Wesley, ISBN: 0-201-64866-0, page 68.) The following articles give some examples of the features that could be implemented using the JUnify library.

API

All code in the library is contained in the unification module. To keep the examples in this section simple, the module name is left out, but it should be present in any real code. The module exposes three public methods and one constant. The two most important methods are unify and variable .

<dt>variable(name, type)</dt>
<dd>Creates a new named variable with an optionally specified type. The returned variable can be used in the patterns when calling `unify`.</dd>

Both the unify and variable methods were demonstrated in the introduction. Note however that the unification works both ways, that is, both patterns can contain variables:

var a = { text: 'Hello', name: variable('name') };
var b = { text: variable('text'), name: 'World!' };

var c = unify(a, b); // c.text = 'Hello', c.name = 'World!'

Variable names can however occur only once per pattern; they must be unique.

JUnify can only perform unification on objects and arrays, not on atoms. The following types are considered atoms: Boolean, Number, String, NaN, Infinity, undefined and null. Functions are not considered atoms, nor can they be unified. Variables can also be typed, so they only match if the types are identical in both patterns.

var a = new Date();
var b = new Boolean(true);
var c = unify(variable('date', Date), a);  // c.date = Mon Jun 23 2008 (…)
var d = unify(variable('date', Date), b);  // d = false

The introduction also demonstrated the use of the wildcard constant _, which can be used to match an item (atom, array, or object) but does not create a binding.

The wildcard constant can also be used instead of an object property name, effectively matching any other object against it (but again, not creating a binding.) It is important that the wildcard symbol is not renamed (i.e. assigned another variable name,) as the library uses it internally to identify wildcard object property names. An example of both uses:

var a = { text: 'Hello', name: 'World!' };
var b = { text: _, name: variable('name') };
var c = { text: _, var: _ };
var d = { text: _, _:_ };

var r = unify(a, a);   // r = {}
var r = unify(a, b);   // r.name = 'World!'
var r = unify(a, c);   // r = false (no match)
var r = unify(a, d);   // r = {} (d can be matched against any object with 
                       //         two properties, one of them being "text")

The last method is visit_pattern, which is used to traverse a pattern using a visitor object with callbacks. This can be used to rewrite custom pattern syntax before passing it to the unify method.

<dl>
    <dt>variable(value)</dt>
    <dd>Called when the pattern visitor encounters a variable. The variable is supplied as a parameter.</dd>
    <dt>wildcard()</dt>
    <dd>Called when the pattern visitor encounters a wildcard variable.</dd>
    <dt>func(value)</dt>
    <dd>Called when the pattern visitor encounters a function. The function is supplied as a parameter.</dd>
    <dt>object(name, value)</dt>
    <dd>Called when the pattern visitor encounters an object. The property name and value are supplied as parameters. The value parameter is visited *after* calling the object callback. The callback function should only return the value. It can not modify the key.</dd>
    
    <dt>atom(value)</dt>
    <dd>Called when the pattern visitor encounters an atom. The atom is supplied as a parameter.</dd>
</dl></dd>

An example of using the visit_pattern method can be found in the article on extracting values from JavaScript objects, where it is used to implement a simplified syntax for extracting object properties.

Example

First include the JUnify library in your web page by adding a script element to the head element. For production use it is recommend to use a minified version of JUnify.

<script type="text/javascript" src="scripts/unification.min.js"></script>

In this example we set up some variable names for convenience (you can also use the fully qualified names without any problems―I would actually recommend it.) Remember that the wildcard constant _ must be an underscore. The methods can be renamed freely. We also create a function to display the results. If the unification succeeds this function will display all the variables and their bindings, or if the unification fails, display an error message.

var _ = unification._;
var $ = unification.variable;
var unify = unification.unify;

function display(value) {
    var name;

    if (value) {
        for (name in value) {
            if (value.hasOwnProperty(name)) {
                alert(name + " = " + value[name]);
            }
        }
    }
    else {
        alert("no match!");
    }
}

It is then possible to use the library to either unify two patterns or extract values from objects.

var a = [1, $('k'), 5, 7, 11];
var b = [1, 3, $('i'), 7, $('j')];

display(unify(a, b)); // i = 5, j = 11, k = 3

var json = {
    article: {
        title: 'Pattern Matching in JavaScript',
        date: new Date(), 
        author: 'Bram Stein'
    }, 
    refid: '12480E'
};

var pattern = { 
    article: { 
        title: $('title'), 
        date: $('date', Date), 
        author: $('author') 
    },
    _ : _ 
};

display(unify(pattern, json)); // title  = 'Pattern Matching in JavaScript',
                               // date   = 'Mon Jun 23 2008 (…)', 
                               // author = 'Bram Stein'

In the first example we unify two arrays, both containing variables. The returned object contains binding for all variables, from both arrays. The second example extracts the title, date and author properties from an article object if the date property has a type of Date. It returns an object with those properties if the match is succesfull.