function kindOf (value) {
  return typeof value === 'object'
    ? Object.prototype.toString.call(value)
      .replace(/^\[object |\]$/g, '')
      .toLowerCase()
    : typeof value
}

function kindOfType (value) {
  // Return the constructor name if not a primative, array or function
  // A more performant `kindOf` with cavets. Must test ES6 after upgrade.
  // Does not handle arguments.
  if (value === null) return 'null'
  if (value === undefined) return 'undefined'

  if (Array.isArray(value)) return 'array'

  if (typeof value === 'string') return 'string'
  if (typeof value === 'boolean') return 'boolean'
  if (typeof value === 'number') return 'number'
  if (typeof value === 'symbol') return 'symbol'
  if (typeof value === 'function') return 'function'

  // this will pick out PlainObjects, regexps, and dates
  // more quickly than a toString.call(). Fails on arguments,
  // not really though --> arguments [object]
  var type = value.constructor.name

  if (type === 'Object') return 'object'
  if (type === 'Date') return 'date'
  if (type === 'RegExp') return 'regexp'

  return type.toLowerCase()
}

function kindOfObjs (value) {
  // a speedy version to obtain common object "types"
  // Does not handle arguments.
  if (typeof value === 'function') return 'function'
  if (Array.isArray(value)) return 'array'
  if (typeof value === 'string') return 'string'

  var type = value.constructor.name

  if (type === 'Object') return 'object'
  if (type === 'Date') return 'date'
  if (type === 'RegExp') return 'regexp'

  return type.toLowerCase()
}

function kindOfSafe (value) {
  // Object.create(null) throws an error. Code below
  // prevents this from happening. Does not handle arguments.
  try {
    if (value === null) return 'null'
    if (value === undefined) return 'undefined'

    if (Array.isArray(value)) return 'array'

    var type = value.constructor.name

    if (type === 'String') return 'string'
    if (type === 'Boolean') return 'boolean'
    if (type === 'Number') return 'number'
    if (type === 'Symbol') return 'symbol'
    if (type === 'Function') return 'function'
    if (type === 'RegExp') return 'regexp'
    if (type === 'Date') return 'date'
    if (type === 'Object') return 'object'

    return type.toLowerCase()
  } catch (err) {
    return Object.prototype.toString.call(value)
      .replace(/^\[object |\]$/g, '')
      .toLowerCase()
  }
}

module.exports = kindOf
module.exports.type = kindOfType
module.exports.objs = kindOfObjs
module.exports.safe = kindOfSafe

@@ -1016,36 +1016,38 @@
   if (type === '
-Date
+RegExp
 ') return 'date'
@@ -1033,36 +1033,38 @@
 egExp') return '
-date
+regexp
 '%0A  if (type ===
@@ -1057,38 +1057,36 @@
   if (type === '
-RegExp
+Date
 ') return 'regex
@@ -1072,38 +1072,36 @@
 'Date') return '
-regexp
+date
 '%0A%0A  return type
@@ -1462,45 +1462,8 @@
 ct'%0A
-  if (type === 'Date') return 'date'%0A
   if
@@ -1498,16 +1498,53 @@
 'regexp'
+%0A  if (type === 'Date') return 'date'
 %0A%0A  retu
@@ -2114,16 +2114,59 @@
 nction'%0A
+    if (type === 'Object') return 'object'%0A
     if (
@@ -2242,51 +2242,8 @@
 ate'
-%0A    if (type === 'Object') return 'object'
 %0A%0A  

update lang/KindOf