From: Nils Goesche
Subject: Pretty Printing With Format
Date: 
Message-ID: <lkwurikvtx.fsf@pc022.bln.elmeg.de>
Hi!

I am trying to figure out how to use the ~< ~:> directive of FORMAT.
For instance, consider:

CL-USER 9 > (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (pprint-logical-block (nil '("foo" "baz" "bar" "bimm"
                                           "bomm" "bumm"))
                (loop for word = (pprint-pop) while word do
                      (princ word)
                      (pprint-exit-if-list-exhausted)
                      (princ #\Space)
                      (pprint-newline :fill))))
foo baz bar bimm
bomm bumm

How would I do that with FORMAT?  I tried stuff like

CL-USER 10 > (let ((*print-right-margin* 20)
                   (*print-miser-width* nil))
               (format t "~<~A~^ ~:_~:>" '("foo" "baz" "bar" "bimm"
                                           "bomm" "bumm")))
foo 

[???] but couldn't find any way to use ~< correctly.  I am using
LispWorks on Linux, BTW, in case this is only a bug...

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9

From: Stefan Schmiedl
Subject: Re: Pretty Printing With Format
Date: 
Message-ID: <ahtgnn$uu140$1@ID-57631.news.dfncis.de>
Guten Morgen, Nils.

On 26 Jul 2002 23:44:58 +0200,
Nils Goesche <······@cartan.de> wrote:
> Hi!
> 
> I am trying to figure out how to use the ~< ~:> directive of FORMAT.
> For instance, consider:
> 
> CL-USER 9 > (let ((*print-right-margin* 20)
>                   (*print-miser-width* nil))
>               (pprint-logical-block (nil '("foo" "baz" "bar" "bimm"
>                                            "bomm" "bumm"))
>                 (loop for word = (pprint-pop) while word do
>                       (princ word)
>                       (pprint-exit-if-list-exhausted)
>                       (princ #\Space)
>                       (pprint-newline :fill))))
> foo baz bar bimm
> bomm bumm
> 
> How would I do that with FORMAT?  I tried stuff like
> 
> CL-USER 10 > (let ((*print-right-margin* 20)
>                    (*print-miser-width* nil))
>                (format t "~<~A~^ ~:_~:>" '("foo" "baz" "bar" "bimm"
>                                            "bomm" "bumm")))
> foo 
> 

22.3.5.2 Tilde Less-Than-Sign: Logical Block

If the at-sign modifier is used with ~<...~:>, the entire
remaining argument list is passed to the directive as its argument.

CL-USER 6 > (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t ··@<[[~;~A~^ ~:_~;]]~:>"
                      '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
[[(foo baz bar bimm bomm bumm)]]

So now you (only :-) need to emulate your loop inside
the block's body:

CL-USER 9 > (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t ··@<[[~;~{~A~^ ~:_~}~;]]~:>"
                      '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
[[foo baz bar bimm
  bomm bumm]]

This is Lispworks on Linux, too.

Sch�nes Wochenende.
s.
From: Nils Goesche
Subject: Re: Pretty Printing With Format
Date: 
Message-ID: <87eldpqmpd.fsf@darkstar.cartan>
Stefan Schmiedl <·@xss.de> writes:

> Guten Morgen, Nils.

Moinmoin!

> On 26 Jul 2002 23:44:58 +0200,
> Nils Goesche <······@cartan.de> wrote:
> > I am trying to figure out how to use the ~< ~:> directive of FORMAT.

> > I tried stuff like
> > 
> > CL-USER 10 > (let ((*print-right-margin* 20)
> >                    (*print-miser-width* nil))
> >                (format t "~<~A~^ ~:_~:>" '("foo" "baz" "bar" "bimm"
> >                                            "bomm" "bumm")))
> > foo 
> 
> 22.3.5.2 Tilde Less-Than-Sign: Logical Block
> 
> If the at-sign modifier is used with ~<...~:>, the entire
> remaining argument list is passed to the directive as its argument.
> 
> CL-USER 6 > (let ((*print-right-margin* 20)
>                   (*print-miser-width* nil))
>               (format t ··@<[[~;~A~^ ~:_~;]]~:>"
>                       '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
> [[(foo baz bar bimm bomm bumm)]]
> 
> So now you (only :-) need to emulate your loop inside
> the block's body:
> 
> CL-USER 9 > (let ((*print-right-margin* 20)
>                   (*print-miser-width* nil))
>               (format t ··@<[[~;~{~A~^ ~:_~}~;]]~:>"
>                       '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
> [[foo baz bar bimm
>   bomm bumm]]

Doh!  ·@< is the _one_ thing I didn't try because I thought ``the
entire remaining argument list'' referred to the remaining
arguments of FORMAT itself.  Thank you very much!

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Pekka P. Pirinen
Subject: Re: Pretty Printing With Format
Date: 
Message-ID: <uado64gur.fsf@globalgraphics.com>
Nils Goesche <···@cartan.de> writes:
> Stefan Schmiedl <·@xss.de> writes:
> > Nils Goesche <······@cartan.de> wrote:
> > > I am trying to figure out how to use the ~< ~:> directive of FORMAT.
> > >
> > > I tried stuff like
> > > 
> > > CL-USER 10 > (let ((*print-right-margin* 20)
> > >                    (*print-miser-width* nil))
> > >                (format t "~<~A~^ ~:_~:>" '("foo" "baz" "bar" "bimm"
> > >                                            "bomm" "bumm")))
> > > foo 
> > 
> > [...]
> > CL-USER 9 > (let ((*print-right-margin* 20)
> >                   (*print-miser-width* nil))
> >               (format t ··@<[[~;~{~A~^ ~:_~}~;]]~:>"
> >                       '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
> > [[foo baz bar bimm
> >   bomm bumm]]
> 
> Doh!  ·@< is the _one_ thing I didn't try because I thought ``the
> entire remaining argument list'' referred to the remaining
> arguments of FORMAT itself.

You were right not to try it, because it does refer to that.  This is
not the right way, although it happens to almost work here.

The one-element list of the remaining FORMAT args becomes the argument
of ~<, and its elements become the arguments for the body segment,
then ~{ picks the first and only one and iterates over it.  This is
only a problem if the argument is not a list:

 CL-USER 4> (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t ··@<[[~;~{~A~^ ~:_~}~;]]~:>"
                      "bumm"))

 Error: "bumm" is not of type cons.
   1 (abort) Return to level 0.
   2 Return to top loop level 0.

as the built-in support can't work.

What you want to do is ·@{ inside the block:

 CL-USER 5> (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t "~<[[···@{~A~^ ~:_~}~;]]~:>"
                      '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
 [[foo baz bar bimm
   bomm bumm]]
 nil

Now the argument of ~< is what you intended, and the body segment gets
all of its elements as arguments, then ·@{ iterates over them.  And
it supports non-lists:

 CL-USER 6> (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t "~<[[···@{~A~^ ~:_~}~;]]~:>"
                      '"bumm"))
 "bumm"
 nil

This kind of thing is particularly useful when you want to handle the
start of the list specially.  Here's an example for pretty-printing
function calls, that special-cases the first element:

 CL-USER 10> (let ((*print-right-margin* 20)
                  (*print-miser-width* nil))
              (format t "~:<~W~^ ····@··@{~W~^ ~_~}~:>"
                      '(frobulator 2 foo #'* bar)))
 (frobulator 2
             foo
             (function *)
             bar)
 nil
-- 
Pekka P. Pirinen
All that glitters has a high refractive index.
From: Nils Goesche
Subject: Re: Pretty Printing With Format
Date: 
Message-ID: <lkk7naih7h.fsf@pc022.bln.elmeg.de>
···············@globalgraphics.com (Pekka P. Pirinen) writes:

> What you want to do is ·@{ inside the block:
> 
>  CL-USER 5> (let ((*print-right-margin* 20)
>                   (*print-miser-width* nil))
>               (format t "~<[[···@{~A~^ ~:_~}~;]]~:>"
>                       '("foo" "baz" "bar" "bimm" "bomm" "bumm")))
>  [[foo baz bar bimm
>    bomm bumm]]
>  nil
> 
> Now the argument of ~< is what you intended, and the body segment gets
> all of its elements as arguments, then ·@{ iterates over them.

Wow.  Very strange.  Slowly it is beginning to make sense in a way...
So, ~< ~:> recursively calls FORMAT on the body with the next argument
(our list) as argument list?  I'd never have thought of that... Thank
you very much!

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9