public String stringApiValue() {
    if (isEmpty()) {
      return "(list)";
    }
    final int fullSlices = (size() / MAX_STRING_API_VALUE_LIST_LITERAL_SIZE);
    if (fullSlices > MAX_STRING_API_VALUE_LIST_LITERAL_SIZE) {
      // @todo this could be improved upon, since the 
      // (NCONC (LIST ... slice1 ... ) (LIST ... slice2 ...))
      // trick could be wrapped with another level of NCONC to handle even bigger
      // expressions, and so on and so forth, requiring only 
      // MAX_STRING_API_VALUE_LIST_LITERAL_SIZE+nesting depth stack space 
      // at any one point ...
      throw new IllegalArgumentException("Cannot currently handle LISTs longer than " + MAX_STRING_API_VALUE_LIST_LITERAL_SIZE * MAX_STRING_API_VALUE_LIST_LITERAL_SIZE);
    }
    final int tailSliceStart = fullSlices * MAX_STRING_API_VALUE_LIST_LITERAL_SIZE;
    final boolean fitsIntoOneSlice = fullSlices == 0;
    final StringBuilder result = new StringBuilder(size() * 20);
    final boolean properList = isProperList();
    if (!fitsIntoOneSlice) {
      // we have multiple slices 
      result.append("(nconc").append(" ");
      for (int i = 0; i < fullSlices; i++) {
        int start = i * MAX_STRING_API_VALUE_LIST_LITERAL_SIZE;
        int end = start + MAX_STRING_API_VALUE_LIST_LITERAL_SIZE;
        // and full slices are ALL proper
        appendSubSlice(result, start, end, true);
      }
    }
    // @note if fullSlices is 0, tailSliceStart will be 0 also
    appendSubSlice(result, tailSliceStart, getProperListSize(), properList);
    if (!fitsIntoOneSlice) {
      result.append(")");
    }
    return result.toString();
  }