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

Re: Format strings are wrong

On Dec 28, 2003, at 9:34 PM, Alex Shinn wrote:

Personally I think there are a lot of things that should be done
different from CL FORMAT, including the already discussed ~P and ~C.
That doesn't make FORMAT a bad thing either.

That doesn't make a modified CL FORMAT a good thing, either. The basic concept remains the same, and there are people who don't like that basic concept.

Formatter procedures can work any way you like; all you need is to
pass some different WRITE-CHAR procedure, which allows for even more
expressiveness.  For instance, you could use SHIFT & RESET to generate
a stream from FORMATTER:

     (format FORMATTER
       (lambda (char) (shift k (stream-cons char (k)))))

You can do this with CL format too.

Pray demonstrate.  (Assume the existence of SHIFT & RESET in CL.)

                                     Or just FORMATTER.


                                                         To avoid
confusion in the discussion, can you use a different name than format?
fmt works, as does funcall (since that's what it is).


If we cared that much about conciseness, we'd all be using Perl or
GOO.  But we don't care _that_ much.

It has it's place though, and if in a quick script I can save typing
four lines by writing a single short format I will.

Sure, it has its place. I use CL-style FORMAT in lots of quick hacks, debug messages, and things like that. But I never go beyond SRFI 28 in those quite limited circumstances, and anyways, for a good formatting SRFI, I'd prefer to have a good formatting mechanism (even if it be not LAMBDA-FORMAT; I merely offer LAMBDA-FORMAT as a potential alternative) to a misshapen derivative of CL-style FORMAT, just as I'd rather have a good fluid variable system, even if it be something I don't believe is optimal -- SRFI 39 --, than have a bad, but historically motivated and occasionally convenient for quick hacks, FLUID-LET
mechanism based on DYNAMIC-WIND + SET!.

                                                     In a larger
application I'm more likely to want to use a (localized) format rule
which I will grab from a config file.  As such, I generally consider

    (display ...)
    (write ...)
    (display ...)

to be bad style in both cases.

But is CL FORMAT good style? In config file formatting things, I'd imagine that string interpolation would be more useful and clearer than either one.

        and not only lets you re-use the format string in parts of
your program, it lets you easily change it at runtime

The same can be said about formatter procedures.

You can only choose from pre-defined formatter procedures, that's a
whole world of difference.

I'm sorry, but I don't understand how you draw this conclusion, or how it's any
different from CL FORMAT.  Could you elaborate, please?

But what you're really doing there is just creating a very limited
language for formatting; it's equivalent to having a very limited
EVAL.  Why not use EVAL?  You could even write an incredibly simple
EVAL that supports only LAMBDA, function application, and the built-in

Because eval is evil.

Oh, please. In most circumstances, yes, EVAL is evil, but when you actually are _evaluating_language_, there's no reason to consider it evil; it's exactly
what you're doing, whatever name it have.

Because restricted languages are easier to verify
and easier to optimize.

Let me quote myself:

                          You could even write an incredibly simple
EVAL that supports only LAMBDA, function application, and the built-in

That looks to me like a restricted language that's pretty damn easy to verify.

Formatter procedures can easily be arbitrarily nested however you like.

As can format strings, as can format lists.

Right. So you while LAMBDA-FORMAT has no advantage here, neither does CL

And you don't need to remember obscure formatting directive syntax
with obscure single-character main names and strange syntax to go
around it (SRFI 29's ~@*, anyone?).

So use longer names.  There's no reason format has to use ~X instead of
~NAME~.  Or some combination of both styles.

Er, please tell me how these differ significantly:

(format #t
"~STRING~ my-local-variable = ~WRITE~; other-variable = ~WRITE~~NEWLINE~"

(format/port (sequence-formatter debug-header " my-local-variable = "
               (write-formatter my-local-variable)
               "; other-variable = " (write-formatter other-variable)
               (char-formatter #\newline)))

(Yes, that would require a trivial change to SEQUENCE-FORMATTER for implicitly
creating string formatters given string arguments.)

Much of your argument has been about conciseness; by extending the names of
the formatting routines, you're going to lose a lot of that.