Using Properties and Tuples to Get Multiple Values from a JavaScript Function

Here’s a word: expando. Here’s a sentence using the word: JavaScript has expando objects.

Expando sounds like a silly made-up word. And it might be. But it’s also an actual word in Latin. It means ‘to spread out.’ The Latin meaning is almost appropriate for JavaScript. Objects in JavaScript are expando objects because properties can be dynamically added (expanding the object) and removed.

var obj = new Object();

// add a property
obj.foo = 'bar';

// remove a property
delete obj.foo;

Since functions in JavaScript are first class objects, properties can be added to functions. A function can be made state-ful by setting a property. In the example below a function named process sets an error property on itself:

function process(input)
{
    process.error = 0;
    ...
    if (...)
    {
        process.error = 1;
    }

    return output;
}

If the process function has never been run, process.error will be undefined.

if (typeof(process.error) != 'undefined')
{
    // test for an error
    ...

In newer versions of JavaScript this test could be written more directly as (process.error != undefined) but using the typeof operator is more portable.

The undefined state could be eliminated by initializing the property outside the function:

var process = function(input) { ... };
process.error = 0;

Are state-ful functions a good practice? It would be problematic if the function can be called again before the previous state has been handled so, in general, keeping state in a function should probably be avoided.

Yes, I just said don’t do the thing I just showed how to do.

Instead of creating state within the function, the function can return a tuple. (Like expando, tuple has a Latin etymology. Did you think you would be learning so much Latin from a blog post on JavaScript?) Tuple is a term used in set theory and by extension the relational database model but in terms of functional programming a tuple is an object that holds several other objects.

A tuple could be implemented as an Array. Using an array would require knowing the position in the array of each specific datum. Depending on positional information is brittle especially for large sets. A better way is an implementation that supports named datums. With named datums the order is irrelevant and the code is more literate.

Here’s the process function modified to use an ad-hoc tuple:

function process(input)
{
    var tuple = new Object();
    tuple.output = null;
    tuple.error = 0;
    ...
    if (...)
    {
        tuple.error = 1;
    }

    return tuple;
}

Using the object literal syntax the tuple object and its properties can be created in one line instead of three:

    var tuple = {output: null, error: 0};

Finally the returned tuple result could be handled as follows:

var result = process(in);
if (result.error == 0)
{
    // do something with result.output
    ...
}

Related Posts:
JavaScript Closures