> > [me]
> > It must be more complex than that.  For one thing, you've omitted the
> > "~" before "28".  For another, this control string always prints a
> 
> Yes, that was a typo.
> 
> and, yes, this prints a newline after every element.
> 
> For the multicolumn ouptut, I was using slightly more complex. (but not 
> much :)

In my opinion, duplicating the required control structure inside the
'format' language quickly leads to unreadable control strings.  You
have to make sure that a left paren is printed only on the first
iteration through the list, and that the newline is replaced by a
right paren on the last iteration.  

In the 'out' macro of my YTools package (available at
 ftp://ftp.cs.yale.edu/pub/mcdermott/software/ytools.tar.gz; 
manual separately available at
 http://www.cs.yale.edu/homes/dvm/papers/ytdoc.pdf), one interleaves
 ordinary Lisp control structures with output commands.  So your
 example would be written

(out (:a (do-columns-1-and-2))
     (:e (repeat :for ((s :in x1 :tail sl)
                       (pre = "(" :then " "))
            (:o (:t 27) (:a pre s)
                (:q ((null (cdr sl))
                     ")")
                    (t :%)))))
     (:t 47) x2
     :%)

where 'x1' and 'x2' are the arguments being output, and the "..." sections are
where the output of the other columns would go.  ('repeat' is my nice
clean alternative to 'loop'; whether to use 'repeat', 'loop', or
'do' is up to the programmer.)  

Note that 'out' uses guide symbols like ':%', ':a' and ':t' that
mirror the format directives ~%, ~a and ~t.  Obviously, it's not as
compact as the format language, but that strikes me as a big
improvement.  In particular, the control structures of format are
replaced by ordinary Lisp control structures.  ':e' means, Switch to
Lisp syntax, and ':o' means, Switch back to 'out' mode.  ':q' is a
special case, which mimics a Lisp cond; 
   (:q (t1 -exps1-) (t2 -exps2-) ...) 
is equivalent to
   (:e (cond (t1 (:o -exps1-)) (t2 (:o -exps2)))).

Rahul Jain's suggested change, where we dispense with the parens in
column 2 and put x2 on every line containing an element of x1, would
be written:

(out (:a (do-columns-1-and-2))
     (:e (repeat :for ((s :in x1))
            (:o (:t 28) (:a s) (:t 47) x2 :%))))

Correct me if I'm wrong, but to do this with 'format' I think you
would have to create a temporary list pairing elements of x1 with x2.
With 'out', you don't need to do anything like that.  In fact, the
whole thing has gotten significantly simpler.

For more on why 'format' is so awful, see my diatribe at
http://www.cs.yale.edu/homes/dvm/format-stinks.html.

Sample data: 

(setq x1 '(129.24.247.137 129.24.243.231 
           129.24.245.23 129.24.241.86 129.24.245.17))
(setq x2 '(445))

(defun do-columns-1-and-2 () "")

-- 
                                             -- Drew McDermott
                                                Yale University CS Dept.


Reply via email to