> > [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.
