code: function parse (types) {
    if (typeof types === 'string') {
      var rtn = []
        , cur = []
        , len = types.length
        , depth = 0
      for (var i=0; i<len; i++) {
        var c = types[i]
  
        if (depth || !/(\d)/.test(c)) {
          cur.push(c)
        }
  
        if (c == '{' || c == '[' || c == '(') {
          depth++
        } else if (c == '}' || c == ']' || c == ')') {
          depth--
          if (!depth)
            add()
        } else if (~DELIMS.indexOf(c) && !depth) {
          add()
        }
      }
      function add () {
        rtn.push(cur.join(''))
        cur = []
        depth = 0
      }
      assert.equal(rtn[1], '@', '_self argument expected as first arg: ' + types)
      assert.equal(rtn[2], ':', 'SEL argument expected as second arg: ' + types)
      return [ rtn[0], rtn.slice(1) ]
    } else if (Array.isArray(types)) {
      return normalizeObjects(types);
    } else {
      var args = types.args
      assert.equal(args[0], '@', '_self argument expected as first arg: ' + types)
      assert.equal(args[1], ':', 'SEL argument expected as second arg: ' + types)
      return [ types.retval, args ]
    }
  }
docs: Parses a "types string" (i.e. `'v@:'`) and returns a "types Array", where the
  return type is the first array value, and an Array of argument types is the
  array second value.