Looking at the library code, the only other way to do this would be to call mapTo which takes a destination collection:
oldSet.mapTo(HashSet<String>()) { getNewStringFromOld(id) }
I’m not sure the default is wrong. The problem is that map might be used in a way that results in a list of non-unique values. If there was a special version of Set.map() that returned a set, you couldn’t use map in that way – any non-unique value would replace the value in the result. I could certainly see the case being made that map should always result in a collection that is the same size as the source collection, and if map created a Set, this wouldn’t always be the case.
If you do this often, perhaps just create your own extension function:
public inline fun <T, R> Iterable<T>.mapToSet(transform: (T) -> R): Set<R> {
return mapTo(HashSet<R>(), transform)
}