code: function(fn, curriedArgs) {
      var curriedLen = curriedArgs.length;
      var partialFn = function() {
        var argIndex = 0, applyArgs = [], self = this, lock = _lock(partialFn), result, i;
        for (i = 0; i < curriedLen; i++) {
          var arg = curriedArgs[i];
          if (isDefined(arg)) {
            applyArgs[i] = arg;
          } else {
            applyArgs[i] = arguments[argIndex++];
          }
        }
        for (i = argIndex; i < arguments.length; i++) {
          applyArgs.push(arguments[i]);
        }
        if (lock === null) {
          lock = curriedLen;
        }
        if (isNumber(lock)) {
          applyArgs.length = min(applyArgs.length, lock);
        }
        // If the bound "this" object is an instance of the partialed
        // function, then "new" was used, so preserve the prototype
        // so that constructor functions can also be partialed.
        if (self instanceof partialFn) {
          self = createInstanceFromPrototype(fn.prototype);
          result = fn.apply(self, applyArgs);
          // An explicit return value is allowed from constructors
          // as long as they are of "object" type, so return the
          // correct result here accordingly.
          return isObjectType(result) ? result : self;
        }
        return fn.apply(self, applyArgs);
      };
      _partial(partialFn, true);
      return partialFn;
    }
docs: *
  @method partial([arg1], [arg2], ...)
  @returns Function
  @short Returns a new version of the function which has part of its arguments
  pre-emptively filled in, also known as "currying".
  @extra `undefined` can be passed as any argument, and is a placeholder that
  will be replaced with arguments passed when the function is executed.
  This allows currying of arguments even when they occur toward the end
  of an argument list (the example demonstrates this more clearly).
  
  @example
  
  logArgs.partial(undefined, 'b')('a') -> logs a, b
  
  @param {any} [arg1]
  @param {any} [arg2]
  
  *