async function sift(arg, func) {
        var result = {};

        for (var item in arg) {
            var entry = arg[item];
            var func_args = hofFuncArgs(func, entry, item, arg);
            // invoke func
            var res = await func.apply(this, func_args);
            if (boolean(res)) {
                result[item] = entry;
            }
        }

        // empty objects should be changed to undefined
        if (Object.keys(result).length === 0) {
            result = undefined;
        }

        return result;
    }
Applies a predicate function to each key/value pair in an object, and returns an object containing
only the key/value pairs that passed the predicate

@param {object} arg - the object to be sifted
@param {object} func - the predicate function (lambda or native)
@returns {object} - sifted object