code: func limit(aObj, bObj interface{}, max int) (string, string) {
  	elidedPrefix := ""
  	elidedASuffix := ""
  	elidedBSuffix := ""
  	a, b := fmt.Sprintf("%#v", aObj), fmt.Sprintf("%#v", bObj)
  
  	if aObj != nil && bObj != nil {
  		if aType, bType := fmt.Sprintf("%T", aObj), fmt.Sprintf("%T", bObj); aType != bType {
  			a = fmt.Sprintf("%s (%s)", a, aType)
  			b = fmt.Sprintf("%s (%s)", b, bType)
  		}
  	}
  
  	for {
  		switch {
  		case len(a) > max && len(a) > 4 && len(b) > 4 && a[:4] == b[:4]:
  			// a is too long, b has data, and the first several characters are the same
  			elidedPrefix = "..."
  			a = a[2:]
  			b = b[2:]
  
  		case len(b) > max && len(b) > 4 && len(a) > 4 && a[:4] == b[:4]:
  			// b is too long, a has data, and the first several characters are the same
  			elidedPrefix = "..."
  			a = a[2:]
  			b = b[2:]
  
  		case len(a) > max:
  			a = a[:max]
  			elidedASuffix = "..."
  
  		case len(b) > max:
  			b = b[:max]
  			elidedBSuffix = "..."
  
  		default:
  			// both are short enough
  			return elidedPrefix + a + elidedASuffix, elidedPrefix + b + elidedBSuffix
  		}
  	}
  }
docs: // limit:
  // 1. stringifies aObj and bObj
  // 2. elides identical prefixes if either is too long
  // 3. elides remaining content from the end if either is too long