Good morning, class.
(defun format-string-delimited-list (stream list string)
(assert (listp list))
(format stream
(format nil "~~{~~a~~^~a~~}" string) list))
(list (format-string-delimited-list nil '(one two three) ", ")
(format-string-delimited-list nil '(left right indifferent) "/"))
-> ("ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
Your assignment: do it in one format.
kt
--
http://www.theoryyalgebra.com/
"Algebra is the metaphysics of arithmetic." - John Ray
"As long as algebra is taught in school,
there will be prayer in school." - Cokie Roberts
"Stand firm in your refusal to remain conscious during algebra."
- Fran Lebowitz
"I'm an algebra liar. I figure two good lies make a positive."
- Tim Allen
Ken Tilton wrote:
> [As long as we are stuck with all these Lisp rugrats we may as well put
> them to work]
>
> Good morning, class.
>
> (defun format-string-delimited-list (stream list string)
> (assert (listp list))
> (format stream
> (format nil "~~{~~a~~^~a~~}" string) list))
>
> (list (format-string-delimited-list nil '(one two three) ", ")
> (format-string-delimited-list nil '(left right indifferent) "/"))
> -> ("ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
>
> Your assignment: do it in one format.
Extra credit: do it in zero formats.
??>> Your assignment: do it in one format.
KT> Extra credit: do it in zero formats.
(defun format-string-delimited-list (list delim)
(reduce (lambda (l r)
(concatenate 'string (string l) delim (string r)))
list))
(defun format-string-delimited-list (stream list delim)
(loop for (this . rest) on list
do (princ this stream)
when rest do (princ delim)))
(defun format-string-delimited-list (stream list delim)
(princ (first list) stream)
(when (rest list)
(princ delim stream)
(format-string-delimited-list stream (rest list) delim)))
if you wish nil/t to be handled as stream -- additional test and
with-output-to-string
)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"choose no life")
> [As long as we are stuck with all these Lisp rugrats we may as well
> put them to work]
>
> Good morning, class.
>
> (defun format-string-delimited-list (stream list string)
> (assert (listp list))
> (format stream
> (format nil "~~{~~a~~^~a~~}" string) list))
>
> (list (format-string-delimited-list nil '(one two three) ", ")
> (format-string-delimited-list nil '(left right indifferent) "/"))
> -> ("ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
>
> Your assignment: do it in one format.
(defun format-string-delimited-list (stream list string)
(assert (listp list))
(format nil
(concatenate 'string "~{~a~^" string "~}")
list))
Regards,
dhl
> [As long as we are stuck with all these Lisp rugrats we may as well
> put them to work]
>
> Good morning, class.
>
> (defun format-string-delimited-list (stream list string)
> (assert (listp list))
> (format stream
> (format nil "~~{~~a~~^~a~~}" string) list))
>
> (list (format-string-delimited-list nil '(one two three) ", ")
> (format-string-delimited-list nil '(left right indifferent) "/"))
> -> ("ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
>
> Your assignment: do it in one format.
(defun format-string-delimited-list (stream list string)
(assert (listp list))
(format stream
Extra credit 2?
Fix/avoid this problem:
>(format-string-delimited-list t '("one" "two" "three") "~")
Error: formatter found unsyntactic format string
(defvar *fsdl-aux* nil)
(defun fsdl-aux (&rest args)
(apply *fsdl-aux* args))
(defun format-string-delimited-list (stream list string)
(let ((*fsdl-aux* (lambda (&rest args)
(declare (ignore args))
(write-string string stream))))
(format stream "~{~a~^~:*~/fsdl-aux/~}" list)))
--
Juho Snellman
Mine's no better than anybody else's, but I don't care, I'm posting
it. Pretty basic:
(defun format-string-delimited-list (stream list string)
(assert (listp list))
(format stream "~:{~a~:^~a~}"
(mapcar #'(lambda (x) (list x string)) list)))
(list "ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
It breaks on:
(format-string-delimited-list t '(a b c) "~")
--
__Pascal Bourguignon__ http://www.informatimago.com/
NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
> Daniel Leidisch <ne...@leidisch.net> writes:
>
>> Ken Tilton <kenny...@optonline.net> writes:
>>
>>> [As long as we are stuck with all these Lisp rugrats we may as well
>>> put them to work]
>>>
>>> Good morning, class.
>>>
>>> (defun format-string-delimited-list (stream list string)
>>> (assert (listp list))
>>> (format stream
>>> (format nil "~~{~~a~~^~a~~}" string) list))
>>>
>>> (list (format-string-delimited-list nil '(one two three) ", ")
>>> (format-string-delimited-list nil '(left right indifferent) "/"))
>>> -> ("ONE, TWO, THREE" "LEFT/RIGHT/INDIFFERENT")
>>>
>>> Your assignment: do it in one format.
>>
>> (defun format-string-delimited-list (stream list string)
>> (assert (listp list))
>> (format stream
>> (concatenate 'string "~{~a~^" string "~}")
>> list))
>
> It breaks on:
>
> (format-string-delimited-list t '(a b c) "~")
Well, so does Ken's version, which makes it part of the scope. ;)
I like Kyle McGivney's solution, which avoids this problem and keeps
it short and simple. A circuitous solution which works with my
purposal might be quoting the tilde characters:
(defun quote-tilde-characters (string)
(let ((position (position #\~ string)))
(if position
(concatenate 'string
(subseq string 0 (1+ position))
"~"
(quote-tilde (subseq string (1+ position))))
string)))
(defun format-string-delimited-list (stream list string)
(assert (listp list))
(format stream
(concatenate 'string "~{~a~^"
(quote-tilde-characters string)
"~}")
list))
Pretty ugly. I like Kyle's much better.
Regards,
dhl
> Ken Tilton wrote:
>> Your assignment: do it in one format.
>
> Extra credit: do it in zero formats.
>
And modifying the functionality slightly...
(defun pprint-delimited-list (stream list string
&key
(prefix "")
(suffix ""))
(pprint-logical-block (stream list
:prefix prefix :suffix suffix)
(pprint-exit-if-list-exhausted)
(loop (princ (pprint-pop) stream)
(pprint-exit-if-list-exhausted)
(princ string stream))))
CL-USER> (list (with-output-to-string (s)
(pprint-delimited-list s '(one two three) ", " :prefix "[" :suffix "]"))
(with-output-to-string (s)
(pprint-delimited-list s '(left right indifferent) "/")))
("[ONE, TWO, THREE]" "LEFT/RIGHT/INDIFFERENT")
CL-USER>
Wade
Thank you. I was at first convinced that there was a way to make
indirection work - like (format t "~?" "~~{~~a~~^~a~~}" (list string)
list), but I couldn't quite shoe-horn that to do what I wanted. I'd
like to see it if somebody could get that. Even if it would be a bitch
to read.
I like Juho's answer because it's the first time in my (admittedly
short) time lisping I've ever seen ~/ used.
Regards,
dhl
Here's my only use of it [and also my only use of escape characters
for symbol names!]... but I use it a *LOT* in my user-mode hardware
debugger code [which also uses a ZERO-X-READER readmacro in its REPL]:
(defun \0x (stream arg colon-p at-sign-p &optional mincol padchar)
"Hexadecimal numeric printing for use with the FORMAT ~/.../ directive.
Outputs ARG to STREAM as \"~(0x~mincol,padX~)\" [default \"~(0x~8,'0X~)\"].
If COLON-P, the entire output will be capitalized instead of lowercased.
If AT-SIGN-P is true, the \"0x\" prefix will be suppressed."
(let* ((fmt1 "~~~:[~;:@~](~:[0x~;~]~~~:[8~;~:*~a~],'~:[0~;~:*~a~]x~~)")
(fmt2 (format nil fmt1 colon-p at-sign-p mincol padchar)))
(format stream fmt2 arg)))
Examples:
> (format t "~/0x/ == ~4/0x/ == ~2/0x/~%" #1=27 #1# #1#)
0x0000001b == 0x001b == 0x1b
NIL
> (format t "~:@/0x/ == ~4:@/0x/ == ~2:@/0x/~%" #1=27 #1# #1#)
0000001B == 001B == 1B
NIL
> (format t "~/0x/~%" (+ 0x1234000 27)) ; demo the readmacro
0x0123401b
NIL
>
I also use it a lot when building data initialization tables in C code:
> (let ((data (loop for i below 24 nconc (list (random 0x100000000)
(random 256))))
(instance "georgey"))
(format t "~%foo_t ~a_foos[~d] = {~
~%~{~<~%~1,68:; {~/0x/, ~2/0x/}~>~^,~}~%};~%"
instance (/ (length data) 2) data))
foo_t georgey_foos[24] = {
{0x21a41a5c, 0x87}, {0x1c63b86e, 0xb4}, {0x894c25d5, 0xa1},
{0x9979b7fe, 0xbb}, {0xc2ad44aa, 0x4d}, {0xe2826239, 0x70},
{0x053b537e, 0x05}, {0x6ac226e8, 0xbe}, {0x1252ea73, 0x20},
{0xe3001d4a, 0x12}, {0x9a006313, 0x31}, {0x299d2f64, 0x54},
{0x90feb745, 0xda}, {0xc7ed257b, 0xc1}, {0xa6e8e18a, 0x51},
{0x0fdb8569, 0xed}, {0x713c27e0, 0xa8}, {0xd975dbac, 0x2d},
{0xb4263772, 0x85}, {0xe6cdaaa9, 0x48}, {0x7db24d29, 0xf8},
{0x87e5aa36, 0xa3}, {0xb56e3dd7, 0xe2}, {0x3cf23443, 0x4e}
};
NIL
>
[Note how the FORMAT string carefully leaves off the comma after the
final element (even though this is no longer required in ANSI C).]
-Rob
-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607