index.js
function(name, options, stack) {
    var args = utils.slice(arguments);
    var opts = {};
    name = args.shift();

    if (!utils.isLoader(options) && lazy.isObject(options)) {
      opts = args.shift();
    }

    opts = opts || {};
    var type = this.getLoaderType(opts);
    opts.loaderType = type;

    var inst = this[type];
    var iterator = this.iterator(type);
    stack = inst.resolve(inst.get(name).concat(args));

    var ctx = { app: this };
    ctx.options = opts;
    ctx.iterator = inst.iterator;
    ctx.loaders = inst;

    return function () {
      var args = [].slice.call(arguments).filter(Boolean);
      var len = args.length, loaders = [];

      while (len-- > 1) {
        var arg = args[len];
        if (!utils.isLoader(arg)) break;
        loaders.unshift(args.pop());
      }

      // combine the `create` and collection stacks
      loaders = stack.concat(inst.resolve(loaders));

      // if loading is async, move the done function to args
      if (type === 'async') {
        args.push(loaders.pop());
      }

      loaders = inst.resolve(loaders);
      if (loaders.length === 0) {
        loaders = inst.resolve(opts.defaultLoader || []);
      }

      var wrapped = loaders.map(opts.wrap || utils.identity);

      // create the actual `load` function
      var load = iterator.call(this, wrapped);
      var res = load.apply(ctx, args);
      return res;
    }.bind(this);
  }
function(name, options, stack) {
    var args = utils.slice(arguments);
    var opts = {};
    name = args.shift();

    if (!utils.isLoader(options) && lazy.isObject(options)) {
      opts = args.shift();
    }

    opts = opts || {};
    var type = this.getLoaderType(opts);
    opts.loaderType = type;

    var inst = this[type];
    var iterator = this.iterator(type);
    stack = inst.resolve(inst.get(name).concat(args));

    var ctx = { app: this };
    ctx.options = opts;
    ctx.iterator = inst.iterator;
    ctx.loaders = inst;

    return function () {
      var args = [].slice.call(arguments).filter(Boolean);
      var len = args.length, loaders = [];

      while (len-- > 1) {
        var arg = args[len];
        if (!utils.isLoader(arg)) break;
        loaders.unshift(args.pop());
      }

      // combine the `create` and collection stacks
      loaders = stack.concat(inst.resolve(loaders));

      // if loading is async, move the done function to args
      if (type === 'async') {
        args.push(loaders.pop());
      }

      loaders = inst.resolve(loaders);
      if (loaders.length === 0) {
        loaders = inst.resolve(opts.defaultLoader || []);
      }

      var wrapped = loaders.map(opts.wrap || utils.identity);

      // create the actual `load` function
      var load = iterator.call(this, wrapped);
      var res = load.apply(ctx, args);
      return res;
    }.bind(this);
  }
Compose the actual `load` function from a loader stack.

```js
var fn = loaders.compose('foo');
// load some files
var files = fn('*.txt');
```

@name .compose
@param  {String} `name` The name of the loader stack to use.
@param  {Object} `options`
@param  {Array|Function} `stack` Additional loader names or functions.
@return {Function}
@api public