[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Format strings are wrong

Gentlemen, with all due respect, and understanding that the following
thoughts may be best expressed in an alternative SRFI; but Upon reviewing
the discussion archive, I feel compelled to voice support of Marc's
opinions; as I don't believe  C'ish embedded numerical format string hacks
actually materially help porting code, or are particularly favored by folks
who are familiar with C; but actually reduce the potential simplicity and
efficiency of mixed text/numerical string formatting which the language
could and arguably should otherwise encourage.

Possibly something along the lines of simply adopting the notion that:
(str-fmt ....) [or (string ...) be extended] to accept mixed string, symbol,
character and numerical arguments, and produces a string resulting from the
concatenation of its argument's string equivalences, by simply converting
its arguments into strings if they're not already strings, using
(number->string ...) or (symbol->string ...) etc.

(define how-many 3)
(define of-what 'apple)

(str-fmt "I ate " 1/2 " of an " of-what ".") -> "I ate 1/2 of an apple."

(str-fmt "I have " how-many " " of-what (if (not (= how-many 1)) "s") ".")

-> "I have 3 apples."


Which is likely sufficient for many things and fairly simple and intuitive.
When more numerical format control is desired, it would seem most straight
forward to simply define a more explicit generic (num->str ....) format
function, which could support parameters such as how to treat signs, digit
separation, field justification, leading/trailing zeros, significant digits,
etc. Possibly:

(num-fmt num-value '(['+|'p] ['s|'z] ['c N] ['m M] ['r R] ['e E]))

[+|p] specifies sign formatting:
    + : signed values:      +1 0 -1
    p : paren'ed negatives:  1 0 (1)
      : default signed neg:  1 0 -1

[s|z] : leading/trailing fill
    s : space leading/trailing fill _1012 12.0__ (_ = space)
    z : zero leading/trailing fill  01012 12.000
      : default none specified (reals always have at least one
        digit leading and trailing the decimal point)

[c N] : N digit comma separator from radix point:  12,423,233.032,343,
      : default none specified

[m M] specifies integer/mantissa digits of significance:
    m 0 : default representation significance, left justified, no fill
    m M : uses M max digits of significant right justified, no fill

[r R] specified the integer/mantissa radix
    r 0: defaults to decimal
    r R: specifies maximum radix digit value (radix - 1)
    (where exponent values print showing xRADIX^decimal-exponent
     i.e. 1.23x10^+32, or 1.0110x2^32, etc)

[e E] specifies minimum number of decimal exponent digits
      which are sign-prefixed etc....

Or something like that so that when more sophisticated numerical formatting
is required, one could define pre-cooked format definition and use it:

(define my-fmt (list '+ 'z 'c 3 'm 6 'r 10 'e 2))
(define my-num 1/4)

(str-fmt "unformated: " my-num ", formatted: " (num-fmt my-num my-fmt))

-> "unformatted: 1/4, formatted: +0.25000x10^+00"

Or something like that, thanks for your time and consideration.