code: function signature(obj, sig) {
      if (typeof obj === 'string') obj = list[obj];
  
      let r = obj.id;
  
      if (sig.args) {
        r += '(';
        sig.args.forEach((arg, idx) => {
          let skip_first, a, value;
          // skip the first bound argument for prototype methods
          skip_first = obj.bound && obj.id.indexOf('#') >= 0;
          a = arg.name;
          // argument can be callback
          if (arg.args) a = signature({ id: a }, arg);
  
          if (!idx && skip_first) return; //a = '@' + a;
  
          if (typeof arg.default_value !== 'undefined') {
            // apply custom stringifier
            value = JSON.stringify(arg.default_value, function (k, v) {
              // FIXME: get rid of quotes, if possible
              if (v instanceof RegExp) v = v.source;
              else if (v === 'null') v = null;
              return v;
            });
            a = a + ' = ' + value;
          }
          // compensate for possibly skipped first argument
          if (idx > (skip_first ? 1 : 0)) a = ', ' + a;
          if (arg.ellipsis) a += '...';
          if (arg.optional) a = '[' + a + ']';
          r += a;
        });
        r += ')';
      }
      return r;
    }
docs: given signature object, recompose its textual representation