In pseudo-code, if I have
(format t "~{~a~%~}~%" (list a b c))
can I somehow obtain
1. a
2. b
3. c
I mean I can think of several ways, but is there something built-in.
I was hoping that ~# might do, but oddly enough I could not find
documentation on it in hyperspec.
Thanks,
Mirko
On Jul 16, 1:29 pm, Mirko <·············@gmail.com> wrote:
> In pseudo-code, if I have
> (format t "~{~a~%~}~%" (list a b c))
>
> can I somehow obtain
> 1. a
> 2. b
> 3. c
>
> I mean I can think of several ways, but is there something built-in.
> I was hoping that ~# might do, but oddly enough I could not find
> documentation on it in hyperspec.
>
> Thanks,
>
> Mirko
http://www.lispworks.com/documentation/lw50/CLHS/Body/22_c.htm
In the paragraph beginning with "In place of a prefix parameter to a
directive,"
It can be used in place of a parameter to a directive, but I don't
think we can translate that into a value being printed.
Personally I wouldn't bother trying to do this with just one format
directive, when you could use a loop to print the output sequentially.
Kyle
On 2009-07-16 13:29:17 -0400, Mirko <·············@gmail.com> said:
> In pseudo-code, if I have
> (format t "~{~a~%~}~%" (list a b c))
>
> can I somehow obtain
> 1. a
> 2. b
> 3. c
CL-USER> (let* ((l '(a b c))
(arglist (loop
for elt in l
for count from 1
collect (list count elt))))
(format t "~:{~a. ~a~%~}~%" arglist))
1. A
2. B
3. C
--
Raffael Cavallaro
On Jul 16, 2:50 pm, Raffael Cavallaro
<················@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2009-07-16 13:29:17 -0400, Mirko <·············@gmail.com> said:
>
> > In pseudo-code, if I have
> > (format t "~{~a~%~}~%" (list a b c))
>
> > can I somehow obtain
> > 1. a
> > 2. b
> > 3. c
>
> CL-USER> (let* ((l '(a b c))
> (arglist (loop
> for elt in l
> for count from 1
> collect (list count elt))))
> (format t "~:{~a. ~a~%~}~%" arglist))
> 1. A
> 2. B
> 3. C
>
> --
> Raffael Cavallaro
Maybe I'm getting off-topic (obviously he wants it all in *one* format
directive) but why wouldn't you just write this?
(let* ((l '(a b c)))
(loop
for elt in l
for count from 1
do (format t "~a. ~a~%" count elt))
(terpri))
From: Pascal J. Bourguignon
Subject: Re: can format ~{...~} enumerate list items?
Date:
Message-ID: <87fxcwdvy4.fsf@galatea.local>
Raffael Cavallaro <················@pas.espam.s.il.vous.plait.mac.com> writes:
> On 2009-07-16 13:29:17 -0400, Mirko <·············@gmail.com> said:
>
>> In pseudo-code, if I have
>> (format t "~{~a~%~}~%" (list a b c))
>> can I somehow obtain
>> 1. a
>> 2. b
>> 3. c
>
> CL-USER> (let* ((l '(a b c))
> (arglist (loop
> for elt in l
> for count from 1
> collect (list count elt))))
> (format t "~:{~a. ~a~%~}~%" arglist))
> 1. A
> 2. B
> 3. C
(defun counting (list &optional (from 1))
(mapcar (let ((i (1- from)))
(lambda (x)
(if (consp x)
(cons (incf i) x)
(list (incf i) x))))
list))
(let ((arguments '(aa bb cc)))
(format t "~:{~A. ~A~%~}" (counting arguments)))
1. AA
2. BB
3. CC
(defun romanize-first (list)
(mapcar (lambda (x) (cons (format nil ··@R" (first x)) (rest x))) list))
(let ((arguments '(aa bb cc dd)))
(format t "~:{~A. ~A~%~}" (romanize-first (counting arguments))))
I. AA
II. BB
III. CC
IV. DD
--
__Pascal Bourguignon__
On 2009-07-16 18:29:17 +0100, Mirko <·············@gmail.com> said:
> I mean I can think of several ways, but is there something built-in.
> I was hoping that ~# might do, but oddly enough I could not find
> documentation on it in hyperspec.
# can be used in place of a prefix argument, and represents the number
of arguments remaining to be processed. So:
? (format t "~{~#d~}~%" '(1 2 3 4 5 6 7))
1 2 3 4 5 67
- probably not what you want. I'd do something like:
(format ... (loop for i upfrom i for j in ... collect (list i j)))
Purists will whine that this conses a whole new list: indeed so. But
you are doing I/O here.
On Thu, 16 Jul 2009 19:42:14 +0100, Tim Bradshaw <···@cley.com> said:
> ...
> (format ... (loop for i upfrom i for j in ... collect (list i j)))
> Purists will whine that this conses a whole new list: indeed so. But
> you are doing I/O here.
We Elegance Fighters submit, in the hope of scoring at least half an
elegance point:
* (format t ····@?~}" (numbered "(~D) ~A~%" '(foo bar baz)))
(1) FOO
(2) BAR
(3) BAZ
NIL
where no conses were unnecessarily harmed, nor no loops looped in
vain, during the evaluation of the above form:
(defmacro numbered (f xs)
"Make an \"iterative numbering formatter\" using format F for the list XS.
The first placeholder in F will be supplied with the number of the current
iteration. F is not evaluated. \"Demo\" grade. Example:
(format t ·····@?~}\" (numbered \"(~D) ~A~%\" '(foo bar baz)))"
`(make-numberer (formatter ,f) ,xs))
(defun make-numberer (f xs)
"NUMBERED's work horse. \"Demo\" grade, if not worse."
(let ((i 0)
(l (list nil)))
(setf (first l)
#'(lambda (s &rest args)
(declare (ignore args))
(if (endp xs) '()
(progn (setf xs (apply f s (incf i) xs))
l))))
l))
(but freedom from side effects was sacrificed somewhat at the altar
of efficiency...).
---Vassil.
P.S. The essential problem with consing a whole new list is not in
the number of conses, but that they all have to be allocated
together, making the risk of running out of memory with a large
original list rear its ugly head.
--
"Even when the muse is posting on Usenet, Alexander Sergeevich?"
Vassil Nikolov wrote:
> On Thu, 16 Jul 2009 19:42:14 +0100, Tim Bradshaw <···@cley.com> said:
>> ...
>> (format ... (loop for i upfrom i for j in ... collect (list i j)))
>
>> Purists will whine that this conses a whole new list: indeed so. But
>> you are doing I/O here.
>
> We Elegance Fighters submit, in the hope of scoring at least half an
> elegance point:
>
> * (format t ····@?~}" (numbered "(~D) ~A~%" '(foo bar baz)))
> (1) FOO
> (2) BAR
> (3) BAZ
> NIL
>
> where no conses were unnecessarily harmed, nor no loops looped in
> vain, during the evaluation of the above form:
>
> (defmacro numbered (f xs)
> "Make an \"iterative numbering formatter\" using format F for the list XS.
> The first placeholder in F will be supplied with the number of the current
> iteration. F is not evaluated. \"Demo\" grade. Example:
> (format t ·····@?~}\" (numbered \"(~D) ~A~%\" '(foo bar baz)))"
> `(make-numberer (formatter ,f) ,xs))
>
> (defun make-numberer (f xs)
> "NUMBERED's work horse. \"Demo\" grade, if not worse."
> (let ((i 0)
> (l (list nil)))
> (setf (first l)
> #'(lambda (s &rest args)
> (declare (ignore args))
> (if (endp xs) '()
> (progn (setf xs (apply f s (incf i) xs))
> l))))
> l))
The problem caught my eye when I saw it posted, so I've been watching
for a solution. I like the output from the test run, and I can
reproduce it in SBCL and CCL, but I get some different results from some
other implementations. E.g., in Allegro:
CL-USER> (format t ····@?~}" (numbered "(~D) ~A~%" '(foo bar baz)))
(1) FOO
NIL
CL-USER> (list (lisp-implementation-type)
(lisp-implementation-version))
("International Allegro CL Free Express Edition"
"8.1 [Mac OS X (Intel)] (Jul 4, 2009 11:13)")
and I get an error in LispWorks (after "(1) FOO" is printed):
CL-USER 3 > (format t ····@?~}" (numbered "(~D) ~A~%" '(foo bar baz)))
(1) FOO
Error: Format iteration infinite loop: body did not use any of the
arguments (#<anonymous interpreted function 200A714A>).:
····@?~}"
^
1 (abort) Return to level 0.
2 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other
options
CL-USER 4 : 1 >
CL-USER> (list (lisp-implementation-type)
(lisp-implementation-version))
("LispWorks" "5.1.2")
Thoughts?
//JT