Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Variable as first argument in format.

10 views
Skip to first unread message

Juan Pardillos

unread,
May 25, 2002, 5:20:13 AM5/25/02
to
Hello,

I don't understand the purpose of using a variable as the first
argument of format. I don't see any difference between assigning the
variable t or nil, as I show in the following interaction:

(defvar *doc* nil)
*DOC*
(format *doc* "Hello")
"Hello"
(setq *doc* t)
T
(format *doc* "Hello")

Hello
NIL
(setq *doc* nil)
NIL

Could someone please explain me which is the utility of using a
variable as the first argument of format instead of, simply, use t or
nil (a good link explaining is ok).

Thanks in advance

David Sletten

unread,
May 25, 2002, 5:54:57 AM5/25/02
to
The reason you would use a variable as the first arg to FORMAT is the
same reason you would use a variable rather than a literal in any
situation--flexibility. The first arg to FORMAT is the destination of
the output created by FORMAT. Typically you would send FORMAT's output
to either a stream or a string. Perhaps the most common destination is
T, which is synonymous here with the stream *STANDARD-OUTPUT*, normally
your terminal. However, you could just as easily specify an arbitrary
stream, such as a file, by assigning a different value to your *DOC*
variable. In this way you could control whether a function prints to the
screen or to a file merely by changing *DOC* (Of course it would make
more sense to use a local variable, e.g., STREAM, in a function).

The other case you tried is where the destination of FORMAT is NIL. This
causes FORMAT to create the specified string and return the string as a
value.

The reason you don't notice a difference when *DOC* is T or NIL is
because of confusion between function return values and side effects.
FORMAT always returns a value. It may or may not cause side effects as
well. This is only confusing at the top-level. You often will not see
FORMAT's return value if it is one of many expressions in a function.

In your first test with *DOC* equal to NIL, the function FORMAT
_returns_ the string "Hello". You can see this by the fact that the
string is enclosed in double quotes. This is how the Lisp printer
outputs strings. Try this:
(concatenate 'string "pung" "foo")
With destination NIL, FORMAT causes no side effect. It simply builds a
string and returns it to you.

However, with destination T, FORMAT causes the string that it builds to
be output to your terminal. The string is printed "as is" without any
quotation marks as you see. This output is a side effect, and FORMAT
still provides a return value in this case. It is NIL. This return value
is output by the Lisp printer immediately after the output created by
FORMAT. Thus you get two lines and no quotes.

Had you bound *DOC* to a file stream, you would not see the string
output to your terminal but merely the NIL return value. Here the side
effect would be to write data to your file.


FORMAT is a very powerful function. With that power naturally comes a
certain amount of complexity. If you want more gory details start here:
http://www.xanalys.com/software_tools/reference/HyperSpec/Body/f_format.htm

David Sletten

Erik Naggum

unread,
May 25, 2002, 6:37:09 AM5/25/02
to
* Juan Pardillos

| I don't understand the purpose of using a variable as the first argument
| of format.

The variable usually holds a stream. t is a designator for a stream so
you do not have to write *standard-output* out in full. nil is sort of a
designator for a constructed string-stream that is discarded upon output
and only its string returnsed.

| I don't see any difference between assigning the variable t or nil, as I
| show in the following interaction:

If you do not see a difference, I cannot help you except to point out
there is one and that you should come back when you see it.

| Could someone please explain me which is the utility of using a variable
| as the first argument of format instead of, simply, use t or nil (a good
| link explaining is ok).

Which textbook or tutorial are you using that is confusing you so? We
need to remove this material from the market or from the Net, as it is
clear that some people are getting horribly confused by some low-quality
introductions out there.
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

70 percent of American adults do not understand the scientific process.

Paul F. Dietz

unread,
May 25, 2002, 9:29:54 AM5/25/02
to
Erik Naggum wrote:

> t is a designator for a stream so
> you do not have to write *standard-output* out in full.

Does the output stream designator T refer to *terminal-io*?
The documentation in the CLHS for FORMAT is unclear, but for
functions like WRITE this is the case.

Paul

Joe Marshall

unread,
May 25, 2002, 10:17:10 AM5/25/02
to

"Paul F. Dietz" <di...@dls.net> wrote in message news:3CEF921C...@dls.net...

For FORMAT, if the stream designator is T it refers to *standard-output*.

This is mentioned in section 22.3, Formatted Output.
I don't know why it isn't specified on the page for the function FORMAT,
but *standard-output* is on the list of things that FORMAT is affected
by, and *terminal-io* is not.

Erik Naggum

unread,
May 25, 2002, 12:38:56 PM5/25/02
to
* Erik Naggum

> t is a designator for a stream so you do not have to write
> *standard-output* out in full.

* "Paul F. Dietz" <di...@dls.net>


| Does the output stream designator T refer to *terminal-io*?

Note that it is not an output stream designator. (The standard says
"nil, t, a stream, or a string with a fill pointer".) t designates
just what I said, *standard-output*.



| The documentation in the CLHS for FORMAT is unclear,

I disagree, but it seems that you bring with you assumptions from prior
successes in reading of the standard. This should not be discouraged
outright, but watching for clues that you must look closer is just as
important. Note that the Affected-by list for format does not include
*terminal-io*, but does include *standard-output*. This should be the
all-important clue.

It may have been useful if the standard said so in the entry on format
itself, but since format is covered elsewhere, the no-redundancy rule
excludes redundant and superfluous repetition of previously stated
requirements. It does say "See section 22.3 on Formatted Output",
however. (In case that is too hard, the pertinent sentence is: "If
destination is t, the output is sent to standard output.")

| but for functions like WRITE this is the case.

For functions that accept an output stream designator (look it up) in
their specification, it is quite trut that nil means *standard-output*,
and t means *terminal-io*, but again, please note that format does not
use an output stream designator and that nil has a _very_ different
meaning than it has for write.

Coby Beck

unread,
May 25, 2002, 2:18:01 PM5/25/02
to

"Juan Pardillos" <sic...@eresmas.com> wrote in message
news:6278687.02052...@posting.google.com...

> Hello,
>
> I don't understand the purpose of using a variable as the first
> argument of format. I don't see any difference between assigning the
> variable t or nil, as I show in the following interaction:

You did not look closely enough.

CL-USER 1 >(format t "where did I go?")
where did I go? ;; this line is the side effect of printing
NIL ;; this line is the return value

CL-USER 2 > (format nil "where did I go?")
"where did I go?" ;; this line is the return value - note the "s

CL-USER 3 > (with-open-file (out "foo.junk" :direction :output
:if-does-not-exist :create)
(format out "where did I go?"))
NIL ;; this is the return value, the string was written to foo.junk


> Could someone please explain me which is the utility of using a
> variable as the first argument of format instead of, simply, use t or
> nil (a good link explaining is ok).

The second argument to format is a stream designator. When this arg is nil,
the string is formatted and returned to the caller. When it is t it is
formatted and sent to whatever *standard-output* is bound to, usually your
listener window. When it is an output stream it is sent to that stream.
HTH.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")

Joel Ray Holveck

unread,
May 27, 2002, 4:19:47 AM5/27/02
to
They are extremely different operations. Your alternative example
(using setq) rebinds the variable with a new string. Passing a string
to format destructively modifies that string by appending the result.

Here's a quick example. It's not made to be a good example of how to
use Lisp, just a slapped-together example of what I just said.

(defun add-foo (string)
(format string "foo"))
(defun add-bar (string)
(format string "bar"))
(defun add-em-up ()
(let ((retval (make-array '(0) :element-type 'character
:adjustable t :fill-pointer t)))
(add-foo retval)
(add-bar retval)
retval))

Cheers,
joelh

0 new messages