# Source: core/extras/function.js

    /**
     * Defines extensions to intrinsic `Function` object.
     * @see {external:Function}
     * @module montage/core/extras/function
     */

    /**
     * @external Function
     */

    require("./object");

    /**
     *  A utility to reduce unnecessary allocations of `function (x) {return x}` in
     *  its many colorful but ultimately wasteful parameter name variations.
     *
     *  @function external:Function.identity
     *  @param {Any} any value
     *  @returns {Any} that value
    */
    Object.defineProperty(Function, "identity", {
        value: function (x) {
            return x;
        },
        writable: true,
        configurable: true
    });

    /**
     * A utility to reduce unnecessary allocations of `function () {}`
     * in its many colorful variations.  It does nothing and thus makes a suitable
     * default in some circumstances.
     *
     * @function external:Function.noop
     */
    Object.defineProperty(Function, "noop", {
        value: function () {
        },
        writable: true,
        configurable: true
    });

    /**
     * A utility for creating a comparator function for a particular aspect of a
     * figurative class of objects.
     *
     * @function external:Function.by
     * @param {Function} relation A function that accepts a value and returns a
     * corresponding value to use as a representative when sorting that object.
     * @param {Function} compare an alternate comparator for comparing the
     * represented values.  The default is `Object.compare`, which
     * does a deep, type-sensitive, polymorphic comparison.
     * @returns {Function} a comparator that has been annotated with
     * `by` and `compare` properties so
     * `Array#sorted` can perform a transform that reduces the need to
     * call `by` on each sorted object to just once.
    */
    Object.defineProperty(Function, "by", {
        value: function (by, compare) {
            compare = compare || Object.compare;
            by = by || Function.identity;
            var compareBy = function (a, b) {
                return compare(by(a), by(b));
            };
            compareBy.compare = compare;
            compareBy.by = by;
            return compareBy;
        },
        writable: true,
        configurable: true
    });