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

Re: Another alternative (Re: format strings are the Right Thing)

Such as possibly something like:

(pipe (fmt:string (fmt-roman 4) " - my graph:\n\n"
                  (fmt-graph 'y-axis "volume" 'x-axis "time"
                             'data (fmt-real my-2d-vector 'prec 4))))

Which could hypothetically produce something like:

-> IV - my graph:

   v     -|             x x
   o 15.00|           x      x
   l     -|         x          x
   u 10.00|                       x
   m     -|       x                  x
   e 5.000|     x                        x
         -| x
        0.000 | 50.00 | 100.0 | 150.0 | 200.0

(although I admit the notion of text graphs are a bit dated)


> From: Paul Schlie <schlie@xxxxxxxxxxx>
> A clisp format procedure among others, seems quite reasonable,
> <input-port> (fmt-clisp <string> <arg> ...) ; to each his own.
> However my gut feel is that format procedures/macros should likely yield
> an <input-ports>, as opposed to directly writing to an <output-port>;
> as it would seem that being able to produce and accept <input-port>
> pipes as arguments would enable the ability to compose relatively
> sophisticated efficient format/text-processing hierarchies quite easily,
> without requiring the use of potentially inefficient and/or cumbersome
> intermediate strings to buffer text between transform layers.
> -paul-
>> From: Shiro Kawai <shiro@xxxxxxxx>
>> I got an impression that this format string discussion has similarity
>> to the regexp pattern language---it defines a mini-language,
>> it has long history tons of variations, it is concise in typical
>> usage but can't be composed well and tend to produce an
>> incomprehensible code when one try to push it too hard.
>> And Olin Shivers showed a solution, SRE.
>> Can't we do the similar thing here?
>> I haven't thought it out well, but the basic idea is like this:
>> [macro] sfmt <SFMT-SPEC> ...
>> Generates a "formatter" closure.  Which takes output port and list of
>> args, and emit the formatted output to the given port.
>> <string>                ; literal string to be displayed.
>> (write [limit N])       ; take next arg and write it (up to N chars)
>> (display [limit N])     ; take next arg and display it (up to N chars)
>> (integer [width N][pad C]) ; format as integer
>> (float [width N][precision P] ...) ; format as flonum
>>  ;; and so on ...
>> (cl-formattr <string>)  ; traditinal CL-style format string
>> And the ability to insert evaluated expression in SFMT-SPEC will allow
>> the programmer to insert other formatter closure into SFMT-SPEC template.
>> (But I have an uneasy feeling about the "implicit backquote" feature
>> of SRE... it looks like it make difficult to write a macro that
>> generates SRE, though  I haven't used SRE extensively so I can't tell
>> for sure).
>> The legacy format can be defined easily, to support the legacy code:
>> [procedure] format output-port string . args
>> == ((sfmt (cl-formatter string)) output-port args)
>> [procedure] format string . args
>> == (let ((out (open-output-string)))
>>     ((sfmt (cl-formatter string)) out args)
>>     (get-output-string out))
>> We could also expose low-level build-in formatter procedure,
>> which could be similar to the one Paul showed.
>> Issues:
>> - What should formatter closure return? - you might want to
>>  switch behavior by whether the output is chopped by the length
>>  limitation or not, for example.   Also the you need to know
>>  how many args are consumed by other formatter procedure embedded
>>  in SFMT-SPEC.
>> - How to handle reordering of the arguments?  Reordering makes
>>  composition of formatters difficult, but is there a better
>>  way to support internationalization of formatting templates?
>>  (maybe a named argument instead of positional argument?)
>> --shiro