As you say, would be good in the core, but almost as good is a simple macro.
\define format-number(n t d p)
<$set name=thousands-separator value="$t$" emptyValue=",">
<$set name=decimal-separator value="$d$" emptyValue=".">
<$set name=decimal-places value="$p$" emptyValue="2">
<$set name=fixed-decimal value={{{ [[$n$]fixed<decimal-places>] }}}>
<$set name=integer value={{{ [<fixed-decimal>split[.]first[]] }}}>
<$set name=remainder value={{{ [<fixed-decimal>split[.]last[]] }}}>
<$set name=length filter="[<integer>length[]]">
<$macrocall $name=each-digit length=<<length>> /><$list filter="[<decimal-places>!match[0]]" variable=nul><<decimal-separator>><<remainder>></$list>
</$set></$set></$set></$set></$set></$set></$set>
\end
\define each-digit(length)
\whitespace trim
<$list filter="[range[1,$length$]]" variable=position>
<$set name=digit filter="[[$(integer)$]split[]nth<position>]">
<$set name=zeros filter="[[$length$]subtract<position>]">
<<digit>>{{{ [<zeros>!match[0]remainder[3]match[0]then<thousands-separator>] }}}
</$set></$set>
</$list>
\end
Regards