From: Roos Van Raadshooven L.A. (Leon)
Subject: "~#" in format, what does it mean?
Date: 
Message-ID: <roosvanr.904514093@biceps>
Hi all,

I was reading the HyperSpec trying to make use of format more effectively.
On the page about format's conditional expression (~[) at the bottom
the example uses "~#[ ...", but I can't find any definition about the use
of ~# or # as a modifier. I grepped the rest of the HyperSpec and found
only one other reference using ~#, on the page about "escape upward" (~^).
Can someone tell me what the use of # in a format expression means?

Thanks,

Leon.

From: Thomas A. Russ
Subject: Re: "~#" in format, what does it mean?
Date: 
Message-ID: <ymi1zpx15jd.fsf@sevak.isi.edu>
There are two special items that you can use in place of a prefix
parameter to a directive.  One of them is "v" or "V", which takes an
argument to format and uses it as a parameter.  The other is "#", which
represents the number of arguments remaining to be processed.

You can find this information in the Hyperspec section 22.3, but it
doesn't tell you a lot more.  The reference in relation to the ~[
directive is that it would be silly to write, for example:

   (format t "~3[zero ~; one ~; two ~; three ~; four ~]")

because that would have the same  effect as just writing

   (format t " three ")

since the clause that is selected is a constant.  An argument to ~[ only
really makes sense for something like:

   (format t "~v[zero ~; one ~; two ~; three ~; four ~]" 3)

where the argument is used to select.  Another use would be for a
variable number of arguments:

   (format t "~#[None ~; ~A ~; ~A and ~A ~; ~A, ~A and ~A~]")
        => None 
   (format t "~#[None ~; ~A ~; ~A and ~A ~; ~A, ~A and ~A~]" 1)
        => 1
   (format t "~#[None ~; ~A ~; ~A and ~A ~; ~A, ~A and ~A~]" 1 2)
        => 1 and 2
   (format t "~#[None ~; ~A ~; ~A and ~A ~; ~A, ~A and ~A~]" 1 2 3)
        => 1, 2 and 3

This would be most useful either embedded in something like ~{ ... ~} or
if the number of arguments was not known at call time, for example in

(defun format-list (item-list stream)
  (apply #'format
	stream
	 "~#[None ~; ~A ~; ~A and ~A ~; ~A, ~A and ~A~]"
	item-list))

------------------------------------------------------------------------

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Steve Gonedes
Subject: Re: "~#" in format, what does it mean?
Date: 
Message-ID: <m2n28lvvls.fsf@KludgeUnix.com>
········@storm.research.kpn.com (Roos Van Raadshooven L.A. (Leon)) writes:

< 
< Hi all,
< 
< I was reading the HyperSpec trying to make use of format more effectively.
< On the page about format's conditional expression (~[) at the bottom
< the example uses "~#[ ...", but I can't find any definition about the use
< of ~# or # as a modifier. I grepped the rest of the HyperSpec and found
< only one other reference using ~#, on the page about "escape upward" (~^).
< Can someone tell me what the use of # in a format expression means?

When the `#' is used in place of a format parameter it will represent
the number of arguments left to process.

(format t "~#[none~:;many~]" 1 2 3)

=> many

(format t "~#[none~:;many~]" )

=> none

I found it useful for use with the condition system. I often write a
single function that will verify the type of a given object - many
times the object can be more than one thing (such as a string or
pathname). Here is a fragment for one of my poly-type-error functions.

(defun poly-type-error (fn thing types)
  (error 'type-error
   :datum thing
   :expected-type types
   :format-control
   ··@<function ··@(~S~); The thing ···@(~S~)', is not a~
                ~:[~{~#[~; or,~] ~(~a~)~^,~}~; ~a~]···@>"
  :format-arguments (list fn thing (atom types) types)))

Sorry it looks so nasty.


> (poly-type-error 'test-function
    'z '(cons string logical-pathname))

=> Error: function TEST-FUNCTION; The thing `Z', is not a cons, string, or,
       logical-pathname.
  [condition type: TYPE-ERROR]


> (poly-type-error 'test-function 'z 'string)

=> Error: function TEST-FUNCTION; The thing `Z', is not a STRING.
  [condition type: TYPE-ERROR]

This usually works better by defining a new condition, say
poly-type-error, then you could avoid such a nasty format - but then
there would be no example. Also there are some examples in CLTL2 pgs
582, and 602. There maybe some examples in Lispcraft but I seemed to
have miplaced it though. I can't find any examples of `#' in the
hyperspec but I'm sure there must be some.

The unfortunate part of this example is

> (poly-type-error 'test-function 'z 'null)

=> Error: function TEST-FUNCTION; The thing `Z', is not a NULL.
  [condition type: TYPE-ERROR].

I hate `not a null', I'd rather `not null', since there is only one
object that can be a null. Sigh. Hope this helps some; have fun.
From: David Bakhash
Subject: Re: "~#" in format, what does it mean?
Date: 
Message-ID: <cxj67f7ol7w.fsf@engc.bu.edu>
········@storm.research.kpn.com (Roos Van Raadshooven L.A. (Leon)) writes:

> On the page about format's conditional expression (~[) at the bottom
> the example uses "~#[ ...", but I can't find any definition about the use
> of ~# or # as a modifier. I grepped the rest of the HyperSpec and found
> only one other reference using ~#, on the page about "escape upward" (~^).
> Can someone tell me what the use of # in a format expression means?

Interesting.  I did the following:

[5] USER(7): (setq x 3)
3
[5] USER(8): (format nil "~#x")
"#<Printer Error>"
[5] USER(9): (format nil "~#x" x)
"3"
[5] USER(10): (format nil "~#y" x)
Error: formatter found unsyntactic format string:
Unknown format directive
~#y
  |

Now, this is weird.  It almost implies that ~#x means to somehow look
at the symbol value of x.  But, upon further examination, it seems as
though some letters which follow the ~# don't produce errors (e.g. `x' 
and `s'), but some do (e.g. `y' and `z').  This leads me to believe
that the # doesn't do anything, though it might be used for some sort
of quoting.

dave
From: Kent M Pitman
Subject: Re: "~#" in format, what does it mean?
Date: 
Message-ID: <sfwaf4jd3pu.fsf@world.std.com>
David Bakhash <·····@bu.edu> writes:

> ········@storm.research.kpn.com (Roos Van Raadshooven L.A. (Leon)) writes:
> 
> > On the page about format's conditional expression (~[) at the bottom
> > the example uses "~#[ ...", but I can't find any definition about the use
> > of ~# or # as a modifier. I grepped the rest of the HyperSpec and found
> > only one other reference using ~#, on the page about "escape upward" (~^).
> > Can someone tell me what the use of # in a format expression means?

Look in 22.3.

> Interesting.  I did the following:
> 
> [5] USER(7): (setq x 3)
> 3
> [5] USER(8): (format nil "~#x")
> "#<Printer Error>"
> [5] USER(9): (format nil "~#x" x)
> "3"
> [5] USER(10): (format nil "~#y" x)
> Error: formatter found unsyntactic format string:
> Unknown format directive
> ~#y
>   |
> 
> Now, this is weird.  It almost implies that ~#x means to somehow look
> at the symbol value of x. 

No, the use of x as an argument looks at the value of x (not the
symbol value, but its lexical value which is only coincidentally the
same thing here).  Doing:

 (let ((x 3)) (format nil "~#x" x))
is identical to doing
 (format nil "~#x" '3)
because functions, including FORMAT, evaluate arguments before passing
to FORMAT.  
 (format nil "~#x" 16)
might be more instructive since ~x is the printer for hex, btw.

> But, upon further examination, it seems as
> though some letters which follow the ~# don't produce errors (e.g. `x' 
> and `s'), but some do (e.g. `y' and `z').  This leads me to believe
> that the # doesn't do anything, though it might be used for some sort
> of quoting.

Uh, well, "#" and "V" (or "v") and "'" and "," are magic in FORMAT parameter
stuff.  (·@" and ":" also have a magic
place, but not to do with parameters.  They are modifiers.) 
Comma obviously separates parameters.    "#" maens "the number of arguments
reamining" and is the same as using that actual number as a parameter except
it changes as the number of remaining arguments changes.  "'" is syntactic
and offers a way to refer to a character as an argument, as in
 (format nil "~3,'0D" 5) => "005"
where neither ' nor the character after it are the format op but rather
are just a way of saying to use character #\0 when padding the number to
be 3-wide.  Neither ~# nor ~V is a format op. V and # are parameters.
~V,V,#,V,#,#,#<op> is a possible single command, though I can't think of
an <op> that wants those args--the point is that the syntax is permissible.
In the case of (format nil "~#x" 3) you could also have written 
(format nil "~1x" 3) or (format nil "~Vx" 1 3).
Unlike #, V consumes an argument and turns it into a parameter.

It's best to look at the doc to figure this all out.  If you look in
the HyperSpec under FORMAT, you get an immediate pointer to 22.3
(Formatted Output) because the details are too long for one function
entry.  22.3 has a lot of sections under it.  But the intro is
relatively brief and does mention the special meaning of ' and V and
#.

Incidentally, style-wise, I usually put V in lowercase and the format
ops in uppercase or vice versa to keep it from looking like V is a
format op.  The other magic characters aren't "bothcase" chars so
don't have this problem.
From: Thomas A. Russ
Subject: Re: "~#" in format, what does it mean?
Date: 
Message-ID: <ymiyas2z6yo.fsf@sevak.isi.edu>
David Bakhash <·····@bu.edu> writes:

> 
> ········@storm.research.kpn.com (Roos Van Raadshooven L.A. (Leon)) writes:
> 
> > On the page about format's conditional expression (~[) at the bottom
> > the example uses "~#[ ...", but I can't find any definition about the use
> > of ~# or # as a modifier. I grepped the rest of the HyperSpec and found
> > only one other reference using ~#, on the page about "escape upward" (~^).
> > Can someone tell me what the use of # in a format expression means?
> 
> Interesting.  I did the following:
>
> [5] USER(7): (setq x 3)
> 3
> [5] USER(8): (format nil "~#x")
> "#<Printer Error>"

Of course.  The ~X format directive expects to get an argument and print
it in hex format.  Given this call, it would be the same as:

 (format nil "~0x")

According to the documentation, the # allows you to use the number of
arguments remaining to be processed as a parameter to a format
directive.  Thus, its use with something like ~X or ~S would be rather
unusual.

> [5] USER(9): (format nil "~#x" x)
> "3"

The same as (format nil "~1x" x)

> [5] USER(10): (format nil "~#y" x)
> Error: formatter found unsyntactic format string:
> Unknown format directive
> ~#y
>   |

Of course.  ~Y is not a valid format directive.  Calling
(format nil "~1y" x) will give you the same sort of error.

> Now, this is weird.  It almost implies that ~#x means to somehow look
> at the symbol value of x.  But, upon further examination, it seems as
> though some letters which follow the ~# don't produce errors (e.g. `x' 
> and `s'), but some do (e.g. `y' and `z').  This leads me to believe
> that the # doesn't do anything, though it might be used for some sort
> of quoting.

Strange conclusion.  That's not what the documentation says about the #
in format.  The reason that some letters cause errors and others don't
is because ~X and ~S are legal format directives while ~Y and ~Z are
not.  The inclusion of the # as a parameter specifier doesn't change the
underlying need to have a legal format directive after the # character.

If you want a really bizarre example, try this one:

(format nil "~#S~#S~#S~#S~#S" 5 4 3 2 1)

"5    4   3  2 1"


Or for more clarity:

(format nil "~#S;~#S;~#S;~#S;~#S;" 5 4 3 2 1)

"5    ;4   ;3  ;2 ;1;"


It prints 5 in a field of width 5, 4 in a field of width 4, ..., 1 in a
field of width 1.



> 
> dave

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu