Sorry for posting an answer to my own question. But since I meanwhile investigated the topic quite deeply I want to share the results and although I haven't found a definitive answer to the question I think this is as far as one can get:
The round() function was added with Tcl 7.0 dating back to the year 1993. Its implementation appeared in tclExpr.c as:
static int
ExprRoundFunc(clientData, interp, args, resultPtr)
ClientData clientData;
Tcl_Interp *interp;
Tcl_Value *args;
Tcl_Value *resultPtr;
{
resultPtr->type = TCL_INT;
if (args[0].type == TCL_INT) {
resultPtr->intValue = args[0].intValue;
} else {
if (args[0].doubleValue < 0) {
if (args[0].doubleValue <= (((double) (long) LONG_MIN) - 0.5)) {
tooLarge:
interp->result = "integer value too large to represent";
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
interp->result, (char *) NULL);
return TCL_ERROR;
}
resultPtr->intValue = (args[0].doubleValue - 0.5);
} else {
if (args[0].doubleValue >= (((double) LONG_MAX + 0.5))) {
goto tooLarge;
}
resultPtr->intValue = (args[0].doubleValue + 0.5);
}
}
return TCL_OK;
}
This initial version returned a native integer type. Later, by adding arbitrary precision integers (TIP237) this was changed to arbitrary precision integers:
https://tcl.tk/cgi-bin/tct/tip/237
The change log does not give a reason why it was chosen to return an integer type. It simply reads:
167. 4/3/93 Changes to expressions:
...
- Expressions now support transcendental and other functions, e.g. sin,
acos, hypot, ceil, and round. Can add new math functions with
Tcl_CreateMathFunc().
The source code does not contain comments describing a reason either. As far as the commit info can be relied upon, it was the decision of the inventor of the language, John Ousterhout himself.
It's interesting to note that most math functions (including ceil() and floor()) simply forwarded to the corresponding C library implementation while round() did not:
#ifndef TCL_NO_MATH
#include <math.h>
#endif
//...
static BuiltinFunc funcTable[] = {
#ifndef TCL_NO_MATH
{"ceil", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) ceil},
{"floor", 1, {TCL_DOUBLE}, ExprUnaryFunc, (ClientData) floor},
// ...
#endif
{"int", 1, {TCL_EITHER}, ExprIntFunc, 0},
{"round", 1, {TCL_EITHER}, ExprRoundFunc, 0},
// ...
};
There was a macro TCL_NO_MATH which offered to exclude the C library math functions. Doing this did not disable floating point support however. To be able to convert floating point types to integers, even when excluding the C library math functions, a discrete implementation of round() was required.
The speculative part of the answer is this:
The focus of thinking might have been on doing conversions, not on mimicking C prototypes. On the one hand it might appeared more convenient to have
set y [expr {round($x)}]
instead of
set y [expr {int(round($x))}]
to get an integer value. On the other hand int() and round() were neighbors in source code. They might have been implemented as "two different ways to convert floating point to integer type" being available even if using TCL_NO_MATH.