A middle ground could be to standardisized only float formatting.
So that there are some primitives that do float formatting,
and various string interpolations and portraying could be
bootstrapped from it. I find some rudimentaries here from ROK:
float_codes(Float, Codes, Format) :-
% like number_codes/2 but only for floats
http://www.cs.otago.ac.nz/staffpriv/ok/pllib.htm
So the standardisation would takle what the ‘%’ operator can
do in Python, when the left argument is a string and the right
argument is a float. But there is much to be demanded, what
if the right argument is an integer, especially a bigint and not
a smallint, a bigint that cannot be converted to float. So ROKs
take is a little outdated, since is not bigint aware.
SWI-Prolog is currently bigint aware:
?- format("abc ~2f def", [123123123123123123123]).
abc 123123123123123123123.00 def
?- format("abc ~2f def", [123123123123123123123.0]).
abc 123123123123123126272.00 def
Trealla Prolog doesn’t tolerate integer:
?- format("abc ~2f def", [123123123123123123123]).
error(type_error(float,123123123123123123123),format/2).
Scryer Prolog does sometimes nonsense for float:
?- format("abc ~2f def", [123123123123123123123.0]).
abc 1.23 def true.
Edit 13.01.2023
My conclusion, to reach the level of SWI-Prolog,
a number_codes with a format parameters is needed, and
not a float_codes that is restricted to floats.
With a number_codes that also accepts integers, it will go
smooth to also format integers, as SWI-Prolog does.
On my side I started defining a new built-in:
atom_number(-Atom, +Atom, +Integer, +Number)
The above built-in takes a slightly different turn, not codes
but atom is the currency for number conversion. The
input atom is ‘f’ or ‘e’, and the input integer is the requested
precision. But it is currently too stupid for bigint, working on it.