From: Wade Humeniuk
Subject: Format ~D Comma Interval Question
Date: 
Message-ID: <a1l2ms$j7t$1@news3.cadvision.com>
I am doing the following with format


CL-USER 8 > (format nil "~:19,'0,' ,4D" 0123456789012345)
"0123 4567 8901 2345"

CL-USER 9 > (format nil "~:19,'0,' ,4D" 10)
"0000000000000000010"

CL-USER 10 >

line 8 is correct, however I want line 9 to return

"0000 0000 0000 0010"

I do not think there is a specified behaviour in the CLHS for line 9, I
assume
LWW is doing it correctly.

Is there another way of doing in it with format?

My work around is.

(defun card-id-string (card-id)
  (with-output-to-string (str) ; this is done because format directive
~:16,'0,' ,4D not working as expected
    (loop for c across (format nil "~16,'0D" card-id)
          for i from 0 below 16
          do
          (when (or (= i 4)
                    (= i 8)
                    (= i 12))
            (write-char #\space str))
          (write-char c str))))

Wade

From: Kent M Pitman
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <sfwn0zlu6tu.fsf@shell01.TheWorld.com>
"Wade Humeniuk" <········@cadvision.com> writes:

> I am doing the following with format
> 
> 
> CL-USER 8 > (format nil "~:19,'0,' ,4D" 0123456789012345)
> "0123 4567 8901 2345"
> 
> CL-USER 9 > (format nil "~:19,'0,' ,4D" 10)
> "0000000000000000010"
> 
> CL-USER 10 >
> 
> line 8 is correct, however I want line 9 to return
> 
> "0000 0000 0000 0010"
> 
> I do not think there is a specified behaviour in the CLHS for line 9, I
> assume LWW is doing it correctly.

Well, it's at least doing it "defensibly", which is all one can hope for.
See below.
 
> Is there another way of doing in it with format?

No.

This is a much disputed area. If you consider what would happen if you used
"~:19,' ,',,4D" you might get a clearer understanding of the problem that has
led some (but not all) implementations to diverge from what you want.

The spec is ill-thought-out here and the problem wasn't discovered until too
late.  Fixing it would require a vote to make some implementations clearly
right and some clearly wrong, and/or an extra arg, and/or some awful 
heuristic like doing something different when spaces were the pad character.

A manual workaround is most reliable and most portable.
From: Barry Margolin
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <Oeq%7.33$dE2.64730@burlma1-snr2>
In article <············@news3.cadvision.com>,
Wade Humeniuk <········@cadvision.com> wrote:
>I am doing the following with format
>
>
>CL-USER 8 > (format nil "~:19,'0,' ,4D" 0123456789012345)
>"0123 4567 8901 2345"
>
>CL-USER 9 > (format nil "~:19,'0,' ,4D" 10)
>"0000000000000000010"
>
>CL-USER 10 >
>
>line 8 is correct, however I want line 9 to return
>
>"0000 0000 0000 0010"
>
>I do not think there is a specified behaviour in the CLHS for line 9, I
>assume
>LWW is doing it correctly.

I agree.  If you were padding with $ characters, would you really expect:

$$$$ $$$$ $$$$ $$10

Padding characters aren't expected to be treated like digits of the value.

>Is there another way of doing in it with format?

There's an example in CLTL2 that seems to do what you want for base 2:

(format nil "~19,,' ,4B" #x1CE) => "0000 0001 1100 1110"

I'm not sure where those leading zeroes came from, since the description of
~D (which ~B references) says that the default padding should be spaces,
and doesn't say anything about printing leading zeroes.  Also, all those
example are missing the : modifier, but that was probably just a typo.

CLHS has this similar example:

(format nil "~19,0,' ,4:B" 3333) =>  "0000 1101 0000 0101"

This is almost like what you tried (except for the radix).  But this
example is missing a "'" character before the 0, so it's obviously not
right.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Steven M. Haflich
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <3C3F1E7A.54EFA8F@pacbell.net>
Barry Margolin wrote:

> Wade Humeniuk <········@cadvision.com> wrote:
> >I am doing the following with format
> >
> >
> >CL-USER 8 > (format nil "~:19,'0,' ,4D" 0123456789012345)
> >"0123 4567 8901 2345"
> >
> >CL-USER 9 > (format nil "~:19,'0,' ,4D" 10)
> >"0000000000000000010"

This is really, really, really easy to miss, Barry and Wade and
everyone else, but the preferred behavior of format here would be
to signal error for the blatantly (:-) malformed format control
string.  It is merely accidental that line 8 happened to do what
was wanted.

The correct syntax is

(format nil "~19,'0,' ,4:D" 0123456789012345)

This doesn't address the issue of whether commas should extend
through the pad chars, but in discussing and testing that it would
be better to use correct format control strings.

> There's an example in CLTL2 that seems to do what you want for base 2:
> 
> (format nil "~19,,' ,4B" #x1CE) => "0000 0001 1100 1110"
> 
> I'm not sure where those leading zeroes came from, since the description of
> ~D (which ~B references) says that the default padding should be spaces,
> and doesn't say anything about printing leading zeroes.  Also, all those
> example are missing the : modifier, but that was probably just a typo.
----------^^^^^^^^^^^^^^^^^^^^^^^^^^

humph!  The accidental "correct" execution of line 8 sure had a lot
of power to misdirect further analysis!

BTW, I didn't see it either until I started checking very carefully.
From: Wade Humeniuk
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <a1nk37$e27$1@news3.cadvision.com>
Thanks Steven, I was not aware of the proper positioning of the semicolon
but LWW does not seem to care much about where the : is placed (except in a
few places).

CL-USER 9 > (format nil "~19,'0,' ,:4D" 0123456789012345)
"0123 4567 8901 2345"

CL-USER 10 > (format nil "~19,':0,' ,4D" 0123456789012345)

Error: In * of (10 #\:) arguments should be of type NUMBER.
  1 (continue) Return a value to use.
  2 Supply a new second argument.
  3 (abort) Return to level 0.
  4 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other
options

CL-USER 11 : 1 > :c 4

CL-USER 12 > (format nil "~19,:'0,' ,4D" 0123456789012345)
"0123 4567 8901 2345"

CL-USER 13 > (format nil "~:19,'0,' ,4D" 0123456789012345)
"0123 4567 8901 2345"

CL-USER 14 > (format nil "~19,'0,' ,4D" 0123456789012345) ; no colon
"0000123456789012345"

CL-USER 15 > (format nil "~19,'0:,' ,4D" 0123456789012345)
"0123 4567 8901 2345"

CL-USER 16 >

Wade
From: Barry Margolin
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <x4I%7.64$dE2.160486@burlma1-snr2>
In article <················@pacbell.net>,
Steven M. Haflich <···@alum.mit.edu> wrote:
>
>Barry Margolin wrote:
>
>> Wade Humeniuk <········@cadvision.com> wrote:
>> >I am doing the following with format
>> >
>> >
>> >CL-USER 8 > (format nil "~:19,'0,' ,4D" 0123456789012345)
>> >"0123 4567 8901 2345"
>> >
>> >CL-USER 9 > (format nil "~:19,'0,' ,4D" 10)
>> >"0000000000000000010"
>
>This is really, really, really easy to miss, Barry and Wade and
>everyone else, but the preferred behavior of format here would be
>to signal error for the blatantly (:-) malformed format control
>string.  It is merely accidental that line 8 happened to do what
>was wanted.
>
>The correct syntax is
>
>(format nil "~19,'0,' ,4:D" 0123456789012345)

You're talking about the incorrect placement of the ":" character, I
presume?  I thought his format strings looked weird, but I didn't bother to
check whether we actually required the : and @ modifiers to come after the
prefix parameters.  I'm not sure why it was necessary to have a prescribed
order, but it's probably just due to the way the original FORMAT
implementors did it -- we didn't want to force anyone to redesign it just
for this minor flexibility.

Regarding signalling an error, I don't think there's anything prohibiting
an implementation-specific extension that allows the modifiers to precede
the prefix parameters.  Of course, the extension could also supply an
entirely different meaning to that syntax, i.e. a : before the prefix args
could mean something different from : after them (it could even be used to
do what the OP wants!).

>> There's an example in CLTL2 that seems to do what you want for base 2:
>> 
>> (format nil "~19,,' ,4B" #x1CE) => "0000 0001 1100 1110"
>> 
>> I'm not sure where those leading zeroes came from, since the description of
>> ~D (which ~B references) says that the default padding should be spaces,
>> and doesn't say anything about printing leading zeroes.  Also, all those
>> example are missing the : modifier, but that was probably just a typo.
>----------^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>humph!  The accidental "correct" execution of line 8 sure had a lot
>of power to misdirect further analysis!

I'm not sure what one had to do with the other.  I don't have a CL
implementation handy, so I never actually executed any of the lines.  So
his incorrect format string didn't affect my analysis (I wasn't even sure
it was malformed).

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Steven M. Haflich
Subject: Re: Format ~D Comma Interval Question
Date: 
Message-ID: <3C3F5636.A8A178EB@pacbell.net>
Barry Margolin wrote:

> Regarding signalling an error, I don't think there's anything prohibiting
> an implementation-specific extension that allows the modifiers to precede
> the prefix parameters.  Of course, the extension could also supply an
> entirely different meaning to that syntax, i.e. a : before the prefix args
> could mean something different from : after them (it could even be used to
> do what the OP wants!).

I only said the _preferred_ behavior would be for the implementation
to reject this syntax.  It is reasonable for implementations to extend
the language syntax to provide increased functionality, but it is IMO
silly to allow trivial, incompatible deviations that have little
expressive benefit and only serve to make the code unportable.