From: Jim Newton
Subject: printing \n
Date: 
Message-ID: <2s7rkmF1gsgq7U1@uni-berlin.de>
in c, perl, python, as well as many other languages printing "\n"
prints a carriage return.  I know that the format function will
print a carriage return when "~%" is encountered.  but is there a
way to print a carriage return as a character?

I ask because i'm converting a program which has a wrapper around
the print function which prints whatever it is given.  Moreover,
if it is given a "\n" or a string containing \n it prints it.
How should i handle this in lisp?

-jim

From: jayessay
Subject: Re: printing \n
Date: 
Message-ID: <m3llep41a3.fsf@rigel.goldenthreadtech.com>
Jim Newton <·····@rdrop.com> writes:

> in c, perl, python, as well as many other languages printing "\n"
> prints a carriage return.

Or some such thing.  This is why this issue is "encapsulated" under
the notion of Newline in Lisp.

> I know that the format function will
> print a carriage return when "~%" is encountered.

No, it performs a Newline.


>  but is there a way to print a carriage return as a character?

From a practical POV: (princ #\Newline) or (terpri)


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: ·········@cern.ch
Subject: Re: printing \n
Date: 
Message-ID: <yzod6015h1h.fsf@cern.ch>
Jim> but is there a way to print a carriage return as a character?

Use (WRITE-CHAR #\Return) to write a "carriage return" if that is
really what you want.

See also:

   #\Newline - should be translated by the implementation,
   (TERPRI)  - the traditional choice

Ole
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opse81htukpqzri1@mjolner.upc.no>
On Sat, 02 Oct 2004 15:19:06 +0200, Jim Newton <·····@rdrop.com> wrote:

> in c, perl, python, as well as many other languages printing "\n"
> prints a carriage return.

Not exactly, \n advances to the next line. (in Lisp #\newline)

on Mac \n gives carriage return
on Unix \n gives line feed
under Windows \n gives line feed followed by carriage return

however \r always gives carriage return (in Lisp #\return)

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s815pF1hv0mfU1@uni-berlin.de>
ok so if (princ #\Newline) prints the newline,
how can i translate something like the following C function
call to lisp?

printf("abc\ndef\nghi\n")



-jim

John Thingstad wrote:
> On Sat, 02 Oct 2004 15:19:06 +0200, Jim Newton <·····@rdrop.com> wrote:
> 
>> in c, perl, python, as well as many other languages printing "\n"
>> prints a carriage return.
> 
> 
> Not exactly, \n advances to the next line. (in Lisp #\newline)
> 
> on Mac \n gives carriage return
> on Unix \n gives line feed
> under Windows \n gives line feed followed by carriage return
> 
> however \r always gives carriage return (in Lisp #\return)
> 
From: Barry Margolin
Subject: Re: printing \n
Date: 
Message-ID: <barmar-E53428.12211702102004@comcast.dca.giganews.com>
In article <···············@uni-berlin.de>,
 Jim Newton <·····@rdrop.com> wrote:

> ok so if (princ #\Newline) prints the newline,
> how can i translate something like the following C function
> call to lisp?
> 
> printf("abc\ndef\nghi\n")

(format "abc~%def~%ghi~%")
or
(format "abc
def
ghi
")
or
(format "abc~Cdef~Cghi~C" #\Newline #\Newline #\Newline)

If the gist of your question is whether there's a symbolic way to 
include newline in a literal string, like \n in C, the answer is no.  
Lisp doesn't have anything like C's \-escapes in string constants; if 
you want to put control characters in there, you put them in literally.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: R. Mattes
Subject: Re: printing \n
Date: 
Message-ID: <pan.2004.10.03.13.28.52.871417@mh-freiburg.de>
On Sat, 02 Oct 2004 12:21:17 -0400, Barry Margolin wrote:


> 
> If the gist of your question is whether there's a symbolic way to 
> include newline in a literal string, like \n in C, the answer is no.  
> Lisp doesn't have anything like C's \-escapes in string constants; if 
> you want to put control characters in there, you put them in literally.

Err, except: 

 (format t "This is a \" quote") 

or 

 (format t "This is a \\ backslash")

They are there, but only the bare minimum.

 Ralf Mattes
From: Matthew Danish
Subject: Re: printing \n
Date: 
Message-ID: <873c0w2arn.fsf@mapcar.org>
"R. Mattes" <··@mh-freiburg.de> writes:
> Err, except: 
> 
>  (format t "This is a \" quote") 
> 
> or 
> 
>  (format t "This is a \\ backslash")
> 
> They are there, but only the bare minimum.

Actually, this has more to do with the Lisp reader.  Backslash
``escapes'' any character, giving it a literal meaning rather than
whatever it was assigned.  So, for example:

(defun \(foo\) () t)
(\(foo\)) => T
(|(FOO)|) => T

or

(let ((\" 1)) \") => 1

-- 
;; Matthew Danish -- user: mrd domain: cmu.edu
;; OpenPGP public key: C24B6010 on keyring.debian.org
From: Barry Margolin
Subject: Re: printing \n
Date: 
Message-ID: <barmar-1BC6CD.20124903102004@comcast.dca.giganews.com>
In article <······························@mh-freiburg.de>,
 "R. Mattes" <··@mh-freiburg.de> wrote:

> On Sat, 02 Oct 2004 12:21:17 -0400, Barry Margolin wrote:
> 
> 
> > 
> > If the gist of your question is whether there's a symbolic way to 
> > include newline in a literal string, like \n in C, the answer is no.  
> > Lisp doesn't have anything like C's \-escapes in string constants; if 
> > you want to put control characters in there, you put them in literally.
> 
> Err, except: 
> 
>  (format t "This is a \" quote") 
> 
> or 
> 
>  (format t "This is a \\ backslash")
> 
> They are there, but only the bare minimum.

I wouldn't consider those anything like C's symbolic escapes.  In Lisp, 
the backslash simply prevents special interpretation of the following 
character.  In C, the backslash introduces a sequence that gets special 
interpretation.  \" and \\ happen to be interpreted as the second 
character of the sequence, so they coincidentally match up with Lisp's 
similar sequences.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Marc Battyani
Subject: Re: printing \n
Date: 
Message-ID: <cjmlub$k4b@library1.airnews.net>
"Jim Newton" <·····@rdrop.com> wrote
> ok so if (princ #\Newline) prints the newline,
> how can i translate something like the following C function
> call to lisp?
>
> printf("abc\ndef\nghi\n")

Have you looked at cl-interpol from Edi Weitz ?

Marc
From: Marco Antoniotti
Subject: Re: printing \n
Date: 
Message-ID: <GSV7d.3$u5.466@typhoon.nyu.edu>
Jim Newton wrote:
> ok so if (princ #\Newline) prints the newline,
> how can i translate something like the following C function
> call to lisp?
> 
> printf("abc\ndef\nghi\n")
> 

First of all the above is a shorthand for

	fprintf(stdout, "abc\ndef\nghi\n");

In Common Lisp you do

	(format t "abc~%edf~%ghi~%")

Cheers

Marco







> 
> 
> -jim
> 
> John Thingstad wrote:
> 
>> On Sat, 02 Oct 2004 15:19:06 +0200, Jim Newton <·····@rdrop.com> wrote:
>>
>>> in c, perl, python, as well as many other languages printing "\n"
>>> prints a carriage return.
>>
>>
>>
>> Not exactly, \n advances to the next line. (in Lisp #\newline)
>>
>> on Mac \n gives carriage return
>> on Unix \n gives line feed
>> under Windows \n gives line feed followed by carriage return
>>
>> however \r always gives carriage return (in Lisp #\return)
>>
> 
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s816vF1hv0mfU2@uni-berlin.de>
is there a lisp implementation of printf that i could use?
Such a function might be useful for such conversions.

-jim


John Thingstad wrote:
> On Sat, 02 Oct 2004 15:19:06 +0200, Jim Newton <·····@rdrop.com> wrote:
> 
>> in c, perl, python, as well as many other languages printing "\n"
>> prints a carriage return.
> 
> 
> Not exactly, \n advances to the next line. (in Lisp #\newline)
> 
> on Mac \n gives carriage return
> on Unix \n gives line feed
> under Windows \n gives line feed followed by carriage return
> 
> however \r always gives carriage return (in Lisp #\return)
> 
From: Pascal Bourguignon
Subject: Re: printing \n
Date: 
Message-ID: <87y8ipp0h9.fsf@thalassa.informatimago.com>
Jim Newton <·····@rdrop.com> writes:

> is there a lisp implementation of printf that i could use?
> Such a function might be useful for such conversions.

Yes. It's named FORMAT.

Or perhaps you want a printf control string translator to FORMAT
control string?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s859lF1hqg6bU1@uni-berlin.de>
no format is not what i'm looking for.

i'm looking for something which will look like the following

(fprintf fp "hello %3.5f %-20s\n" 2.345567 "world")

-jim

Pascal Bourguignon wrote:
> Jim Newton <·····@rdrop.com> writes:
> 
> 
>>is there a lisp implementation of printf that i could use?
>>Such a function might be useful for such conversions.
> 
> 
> Yes. It's named FORMAT.
> 
> Or perhaps you want a printf control string translator to FORMAT
> control string?
> 
From: Pascal Bourguignon
Subject: Re: printing \n
Date: 
Message-ID: <87lleposrf.fsf@thalassa.informatimago.com>
Jim Newton <·····@rdrop.com> writes:

> no format is not what i'm looking for.
> 
> i'm looking for something which will look like the following
> 
> (fprintf fp "hello %3.5f %-20s\n" 2.345567 "world")

Then why don't you implement it with the indications that John gave you?
It should not take more than half a day.

So, have you so many fprintf control strings to translate that it
would be more efficient to do it automatically?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

To vote Democrat or Republican, it's like changing of cabin in the Titanic.
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s8dd8F1hj6evU1@uni-berlin.de>
Pascal Bourguignon wrote:
> Then why don't you implement it with the indications that John gave you?
> It should not take more than half a day.
> 
> So, have you so many fprintf control strings to translate that it
> would be more efficient to do it automatically?
> 



Yes, this is a good question.  I'm not yet sure how many such cases
of them i'll have.
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opse830lygpqzri1@mjolner.upc.no>
On Sat, 02 Oct 2004 16:54:12 +0200, Jim Newton <·····@rdrop.com> wrote:

> is there a lisp implementation of printf that i could use?
> Such a function might be useful for such conversions.
>
> -jim

No, not that I am aware of.
Lisp has a more powerfull printer called format but it's syntax is quite  
different.

some that will get you started are

(format stream string args)

stream = t    - print to stdout -- printf
stream = nil  - return string   -- sprintf
stream = file pointer           -- fprintf (see open and with-open-file in  
hyperspec)

string

~& - fresh line -- create a new line if not already on one
~% - like \n
~D - like %d
~F - like %f
~A - like %s
~C - like %c

This is just the tip of the iceberg. Studying all the options of format is  
work but worth it.
http://www.lispworks.com/reference/HyperSpec/Body/f_format.htm
http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm

> how can i translate something like the following C function
> call to lisp?
> printf("abc\ndef\nghi\n")

(format t "abc~%def~%nghi~%")

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s85j9F1ijiqgU1@uni-berlin.de>
yes, i realize that the FORMAT function is much more powerful
than printf, but what if i need printf?

it should be fairly straightforward to write a version of
printf which just either wraps FORMAT, or implements it
from scratch.

-jim


John Thingstad wrote:
> On Sat, 02 Oct 2004 16:54:12 +0200, Jim Newton <·····@rdrop.com> wrote:
> 
>> is there a lisp implementation of printf that i could use?
>> Such a function might be useful for such conversions.
>>
>> -jim
> 
> 
> No, not that I am aware of.
> Lisp has a more powerfull printer called format but it's syntax is 
> quite  different.
> 
> some that will get you started are
> 
> (format stream string args)
> 
> stream = t    - print to stdout -- printf
> stream = nil  - return string   -- sprintf
> stream = file pointer           -- fprintf (see open and with-open-file 
> in  hyperspec)
> 
> string
> 
> ~& - fresh line -- create a new line if not already on one
> ~% - like \n
> ~D - like %d
> ~F - like %f
> ~A - like %s
> ~C - like %c
> 
> This is just the tip of the iceberg. Studying all the options of format 
> is  work but worth it.
> http://www.lispworks.com/reference/HyperSpec/Body/f_format.htm
> http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm
> 
>> how can i translate something like the following C function
>> call to lisp?
>> printf("abc\ndef\nghi\n")
> 
> 
> (format t "abc~%def~%nghi~%")
> 
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opse86zij5pqzri1@mjolner.upc.no>
On Sat, 02 Oct 2004 18:09:01 +0200, Jim Newton <·····@rdrop.com> wrote:

> yes, i realize that the FORMAT function is much more powerful
> than printf, but what if i need printf?
>
> it should be fairly straightforward to write a version of
> printf which just either wraps FORMAT, or implements it
> from scratch.
>
> -jim
>

Indeed, but I'm afraid you will have to roll your own.
As I said you can do the same and more with format.
The one reson I can think of to use printf is if you need to read files  
containing printf
or printf style strings and then execute them. Hardly a common occurence.
(Remember that Lisp (not Common Lisp) predates C and like FORTRAN does not
follow the conventions you are used to in the C library.)

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Gareth McCaughan
Subject: Re: printing \n
Date: 
Message-ID: <87655sdhcv.fsf@g.mccaughan.ntlworld.com>
Jim Newton <·····@rdrop.com> writes:

> yes, i realize that the FORMAT function is much more powerful
> than printf, but what if i need printf?

How could it come about that you *need* printf? I mean,
are you also concerned that you'll need a looping macro
with syntax like

    (for (setf i 0) (< i 10) (incf i)
      ... do stuff ...)

? I hope the answer is: No, because you can do that more
lispily using mechanisms that Lisp already has and there's
no particular advantage to imitating C syntax here. If you
agree, why should printf/FORMAT be any different?

Incidentally, did you take note of the responses that
explained that you can just embed a literal newline in
your string?

If you really, truly *need* C-style string literals,
with backslashed escapes, then the thing to do would
be to diddle the readtable so that, say, #E"foo\t\n\r"
reads as a string containing the characters #\f, #\o,
#\o, #\Tab, #\Newline, #\Return. Shouldn't be hard;
something along the lines of ...

(defvar *string-escape-character* #\\)

(defvar *string-escape-table*
  ;; built with LIST and CONS so it's legal to modify it
  (list
    (cons #\t #\Tab)
    (cons #\n #\Newline)
    (cons #\r #\Return)
    ...))

(defvar *escaped-string-delimiters*
  (list #\" #\'))

(set-dispatch-macro-character #\# #\E
  (lambda (stream sub-char infix-arg)
    (declare (ignore sub-char infix-arg))
    (let ((delimiter (read-char stream))
          (escaped nil))
      (assert (member delimiter *escaped-string-delimiters*))
      (coerce (loop for next-char = (read-char stream) nconc
                (cond
                  (escaped
                    (progn (setf escaped nil)
                           (list (or (cdr (assoc next-char *string-escape-table*))
                                     next-char))))
                  ((char= next-char delimiter)
                    (loop-finish))
                  ((char= next-char *string-escape-character*)
                   (setf escaped t)
                   nil)
                  (t (list next-char))))
              'string))))

although that's rather inefficient and doesn't cope very gracefully
with unexpected situations like ill-delimited strings.

-- 
Gareth McCaughan
.sig under construc
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s8gorF1i7ammU1@uni-berlin.de>
the reason i was originally wanting the printf capability
is because i'm converting a program which uses them. And in
this program sometimes the format string is passed as a
variable.  It is not always a literal format string that
i can re-interpret in terms of FORMAT.

In my case the original program is in Python, but there
would be the same problem if someone was converting from
Perl or from C or C++.  So it is a bit suprising that
there is not simply a library function for doing this.

-jim

Gareth McCaughan wrote:
> Jim Newton <·····@rdrop.com> writes:
> 
> 
>>yes, i realize that the FORMAT function is much more powerful
>>than printf, but what if i need printf?
> 
> 
> How could it come about that you *need* printf? I mean,
> are you also concerned that you'll need a looping macro
> with syntax like
> 
>     (for (setf i 0) (< i 10) (incf i)
>       ... do stuff ...)
> 
> ? I hope the answer is: No, because you can do that more
> lispily using mechanisms that Lisp already has and there's
> no particular advantage to imitating C syntax here. If you
> agree, why should printf/FORMAT be any different?
> 
> Incidentally, did you take note of the responses that
> explained that you can just embed a literal newline in
> your string?
> 
> If you really, truly *need* C-style string literals,
> with backslashed escapes, then the thing to do would
> be to diddle the readtable so that, say, #E"foo\t\n\r"
> reads as a string containing the characters #\f, #\o,
> #\o, #\Tab, #\Newline, #\Return. Shouldn't be hard;
> something along the lines of ...
> 
> (defvar *string-escape-character* #\\)
> 
> (defvar *string-escape-table*
>   ;; built with LIST and CONS so it's legal to modify it
>   (list
>     (cons #\t #\Tab)
>     (cons #\n #\Newline)
>     (cons #\r #\Return)
>     ...))
> 
> (defvar *escaped-string-delimiters*
>   (list #\" #\'))
> 
> (set-dispatch-macro-character #\# #\E
>   (lambda (stream sub-char infix-arg)
>     (declare (ignore sub-char infix-arg))
>     (let ((delimiter (read-char stream))
>           (escaped nil))
>       (assert (member delimiter *escaped-string-delimiters*))
>       (coerce (loop for next-char = (read-char stream) nconc
>                 (cond
>                   (escaped
>                     (progn (setf escaped nil)
>                            (list (or (cdr (assoc next-char *string-escape-table*))
>                                      next-char))))
>                   ((char= next-char delimiter)
>                     (loop-finish))
>                   ((char= next-char *string-escape-character*)
>                    (setf escaped t)
>                    nil)
>                   (t (list next-char))))
>               'string))))
> 
> although that's rather inefficient and doesn't cope very gracefully
> with unexpected situations like ill-delimited strings.
> 
From: Gareth McCaughan
Subject: Re: printing \n
Date: 
Message-ID: <87fz4wbs6s.fsf@g.mccaughan.ntlworld.com>
Jim Newton <·····@rdrop.com> writes:

> the reason i was originally wanting the printf capability
> is because i'm converting a program which uses them. And in
> this program sometimes the format string is passed as a
> variable.  It is not always a literal format string that
> i can re-interpret in terms of FORMAT.

Aha, I understand. But I think you may be confused
about one point.

The interpretation of things like "\n" in C or C++
string literals is done by the compiler, at (in Lisp-speak)
read time. The string that you enter as "foo\n" in a
C or C++ program contains no backslashes; the characters
in it are 'f', 'o', 'o', newline. (Plus the terminating
0-byte.) Interpreting backslashes is not the job of
printf, nor of anything else in the C library; by the
time the program runs at all, the backslashes are gone.

    (The same is true in Python and also, more or less,
    in Perl. "More or less" because Perl does all sorts
    of funky interpolation things on double-quoted strings,
    which are therefore not really string *literals* as
    such.)

So (if I'm understanding you right) what you need
for those newlines is not a version of printf in Lisp
that understands backslash escapes; the printf in C
doesn't understand backslash escapes, nor does it
need to. What you want is a syntax for string literals
that lets you put newlines into strings. Lisp has that:
you just, um, put the newlines in directly.

    (setf a-string "I am the walrus.
    They are the eggmen.
    Goo goo g'djoo.")

produces a string with two newlines in it. If that's
not enough then you could try something like the code
in the grandparent of this article.

Still, if you have format strings being constructed
then indeed you can't do your porting simply by
diddling the string literals. But, depending on just
how those format strings are constructed and why,
you may want to consider a different approach. The
main reason I've found for building format strings
in Python (though not the only one) is to determine
at runtime the field width or precision you need.
CL's FORMAT function lets you do that more directly,
so you may be able to lose the dynamically-built
format strings altogether. That seems like a better
option than reimplementing Python's % operator in
Common Lisp, on the whole.

> In my case the original program is in Python, but there
> would be the same problem if someone was converting from
> Perl or from C or C++.  So it is a bit suprising that
> there is not simply a library function for doing this.

Not very much converting from C or C++ to Lisp gets
done. If you have a program in C or C++ that works
well enough, why not leave it in C or C++? :-)

Conversion from Python makes a bit more sense; I'm
guessing the issue is that the Python program doesn't
run fast enough for your needs. But it still isn't
common enough for anyone to have written a CL implementation
of Python's string formatting (which isn't quite the same
as C's...).

-- 
Gareth McCaughan
.sig under construc
From: Hartmann Schaffer
Subject: Re: printing \n
Date: 
Message-ID: <rtK7d.2121$Cb5.14372@newscontent-01.sprint.ca>
Gareth McCaughan wrote:
> ...
> So (if I'm understanding you right) what you need
> for those newlines is not a version of printf in Lisp
> that understands backslash escapes; the printf in C
> doesn't understand backslash escapes, nor does it
> need to. What you want is a syntax for string literals
> that lets you put newlines into strings. Lisp has that:
> you just, um, put the newlines in directly.
> 
>     (setf a-string "I am the walrus.
>     They are the eggmen.
>     Goo goo g'djoo.")
> 
> produces a string with two newlines in it. If that's
> not enough then you could try something like the code
> in the grandparent of this article.

the original message seems to suggest that that is his problem, but he 
still has to deal with formatting directives like %5d

> ...

hs
From: Paul Foley
Subject: Re: printing \n
Date: 
Message-ID: <m2is9oosej.fsf@mycroft.actrix.gen.nz>
On Sat, 02 Oct 2004 23:47:34 GMT, Gareth McCaughan wrote:

> you may want to consider a different approach. The
> main reason I've found for building format strings
> in Python (though not the only one) is to determine
> at runtime the field width or precision you need.
> CL's FORMAT function lets you do that more directly,

So does Python (via C): "%*.*s", etc.

[The one thing FORMAT is missing that I always want is a maximum field
width, like the above printf control string]


You could use FFI to call sprintf

-- 
Malum est consilium quod mutari non potest             -- Publilius Syrus

(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: Thomas A. Russ
Subject: Re: printing \n
Date: 
Message-ID: <ymipt3ua0wr.fsf@sevak.isi.edu>
Paul Foley <·······@actrix.gen.nz> writes:

> 
> So does Python (via C): "%*.*s", etc.
> 
> [The one thing FORMAT is missing that I always want is a maximum field
> width, like the above printf control string]

Yes, it is a bit unfortunate that the colinc argument to format
directives like ~A, ~S and ~< is not allowed to be zero.  If that were
an allowed value, then one could get the behavior indicated without
needing any additional directives or arguments.  Of course, one then
wouldn't get both minimum and maximum field widths...


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Christopher C. Stacy
Subject: Re: printing \n
Date: 
Message-ID: <uacv4pi25.fsf@news.dtpq.com>
Jim Newton <·····@rdrop.com> writes:

> yes, i realize that the FORMAT function is much more powerful
> than printf, but what if i need printf?

You do the same thing you would do if you needed FORMAT in C.
(However, it will be a damn sight easier to do this in Lisp.)

> it should be fairly straightforward to write a version of
> printf which just either wraps FORMAT, or implements it
> from scratch.

Yup!
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opse9x8pnmpqzri1@mjolner.upc.no>
On Sat, 02 Oct 2004 18:09:01 +0200, Jim Newton <·····@rdrop.com> wrote:

> yes, i realize that the FORMAT function is much more powerful
> than printf, but what if i need printf?
>
> it should be fairly straightforward to write a version of
> printf which just either wraps FORMAT, or implements it
> from scratch.
>
> -jim
>

I had some time to kill so here goes.
I took the liberty of using Gareth McCaughan's code for extending the read  
macro.
A crude and inefficient version of printf.
It needs more work but I think you could take it from here.

CL-USER 111 > (printf #C"int=%10d\tfloat=%10.3f\n" 2 3.1415)
int=         2	float=     3.142
NIL


(defvar *string-escape-character* #\\)

(defvar *string-escape-table*
   ;; built with LIST and CONS so it's legal to modify it
   (list
     (cons #\t #\Tab)
     (cons #\n #\Newline)
     (cons #\r #\Return)))

(defvar *escaped-string-delimiters*
   (list #\" #\'))

(set-dispatch-macro-character #\# #\C
   (lambda (stream sub-char infix-arg)
     (declare (ignore sub-char infix-arg))
     (let ((delimiter (read-char stream))
           (escaped nil))
       (assert (member delimiter *escaped-string-delimiters*))
       (coerce (loop for next-char = (read-char stream) nconc
                 (cond
                   (escaped
                     (progn (setf escaped nil)
                            (list (or (cdr (assoc next-char  
*string-escape-table*))
                                      next-char))))
                   ((char= next-char delimiter)
                     (loop-finish))
                   ((char= next-char *string-escape-character*)
                    (setf escaped t)
                    nil)
                   (t (list next-char))))
               'string))))

(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
(defvar *format-translation-table*
   (list
    (cons #\d "D")
    (cons #\f "F")
    (cons #\s "A")
    (cons #\c "C")))

(defun read-int (stream)
   (if (not (member (peek-char nil stream) *digits*))
       nil
     (loop with digits =
           (loop for char = (read-char stream) until (not (member char  
*digits*))
                 collecting (- (char-code char) (char-code #\0))
                 finally (unread-char char stream))
           for list = digits then (cdr list) until (null list)
           as prod = (expt 10 (1- (length digits))) then (/ prod 10)
           summing (* prod (car list)))))

(defun printf (format &rest args)
   (with-input-from-string (stream format)
     (loop with vals = args
           with val = (car args)
           for char = (read-char stream nil 'EOF) until (not (characterp  
char)) do
           (if (char= char #\%)
               (let ((first "~") (second "") (third "") (fourth "") fifth)
                 (let ((val (read-int stream)))
                   (when val (setf second (format nil "~D" val))))
                 (when (char= (peek-char nil stream) #\.)
                   (setf char (read-char stream))
                   (setf third ",")
                   (let ((val (read-int stream)))
                     (when val (setf fourth (format nil "~D" val))))
                   )
                 (setf char (read-char stream))
                 (setf fifth (cdr (assoc char *format-translation-table*)))
                 (format t (concatenate 'string first second third fourth  
fifth) val)
                 (setf vals (cdr vals) val (car vals)))
             (princ char)))))



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opsfaltbq3pqzri1@mjolner.upc.no>
On Sun, 03 Oct 2004 05:20:39 +0200, John Thingstad  
<··············@chello.no> wrote:

> I had some time to kill so here goes.
> I took the liberty of using Gareth McCaughan's code for extending the  
> read macro.
> A crude and inefficient version of printf.
> It needs more work but I think you could take it from here.

Better!
Created a macro printf->format.
1. expands at compile time so it has no overhead compared to format
2. I noticed that I was converting the number part to a integer only to  
convert it back to string
    The new one only reads the charactes and puts them into a string
    It altso hanles sign

CL-USER 7 > (format t (printf->format #C"int=%10d\tfloat=%10.3f\n") 2  
3.1415)
int=         2	float=     3.142
NIL

<Gareth McCaughan's code>
...

(defvar *digits* '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
(defvar *sign* '(#\+ #\-))
(defvar *format-translation-table*
   (list
    (cons #\d #\D)
    (cons #\f #\F)
    (cons #\s #\A)
    (cons #\c #\C)))

(defun read-int-string (istream)
   (with-output-to-string (ostream)
     (when (member (peek-char nil istream) *sign*)
       (write-char (read-char istream) ostream))
     (loop for char = (read-char istream) until (not (member char *digits*))
           do (write-char char ostream)
           finally (unread-char char istream))))

(defmacro printf->format (format)
   (with-output-to-string (ostream)
     (with-input-from-string (istream format)
       (loop for char = (read-char istream nil 'EOF) until (not (characterp  
char)) do
             (if (char= char #\%)
                 (progn
                   (write-char #\~ ostream)
                   (write-string (read-int-string istream) ostream)
                   (when (char= (peek-char nil istream) #\.)
                     (setf char (read-char istream))
                     (write-char #\, ostream)
                     (write-string (read-int-string istream) ostream))
                   (setf char (read-char istream))
                   (write-char (cdr (assoc char  
*format-translation-table*)) ostream))
               (princ char ostream))))))

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: printing \n
Date: 
Message-ID: <87655s9dua.fsf@qrnik.zagroda>
"John Thingstad" <··············@chello.no> writes:

> Better!
> Created a macro printf->format.
> 1. expands at compile time so it has no overhead compared to format

The format needs not to be known at compile time.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opsfaptsk0pqzri1@mjolner.upc.no>
On Sun, 03 Oct 2004 14:38:05 +0200, Marcin 'Qrczak' Kowalczyk  
<······@knm.org.pl> wrote:

> "John Thingstad" <··············@chello.no> writes:
>
>> Better!
>> Created a macro printf->format.
>> 1. expands at compile time so it has no overhead compared to format
>
> The format needs not to be known at compile time.
>

fine...
change (defmacro prinf->format to (defun printf->format
and perhaps add (defmacro m-printf->format (format) (printf->format  
format))

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Kalle Olavi Niemitalo
Subject: Re: printing \n
Date: 
Message-ID: <87k6u7g2p1.fsf@Astalo.kon.iki.fi>
"John Thingstad" <··············@chello.no> writes:

> change (defmacro prinf->format to (defun printf->format
> and perhaps add (defmacro m-printf->format (format) (printf->format
> format))

A compiler macro might be more convenient.

  (define-compiler-macro printf->format (&whole whole printf)
    (if (stringp printf)
      ;; The parameter is a string literal; convert it at compile
      ;; time and assume the result is self-evaluating.  If this
      ;; causes a nested call to the compiler macro, the argument
      ;; form will be the symbol PRINTF, so any recursion will
      ;; stop short.
      (printf->format printf)
      ;; Otherwise, decline to expand the form.
      whole))
From: Gareth McCaughan
Subject: Re: printing \n
Date: 
Message-ID: <87hdpb8lsb.fsf@g.mccaughan.ntlworld.com>
John Thingstad wrote:

> (defvar *string-escape-table*
>    ;; built with LIST and CONS so it's legal to modify it
>    (list
>      (cons #\t #\Tab)
>      (cons #\n #\Newline)
>      (cons #\r #\Return)))

(For actual use you'd probably want to include the full
set of C escapes here.)

> (set-dispatch-macro-character #\# #\C

Please don't use #C for this; it already has a useful
meaning. I suppose you could grab the existing macro
dispatch character function (what's the right term
for those? there must be something more concise) and
use PEEK-CHAR to call that if you see a ( following
the #C, but surely it's better to use an unclaimed
macro dispatch character?

-- 
Gareth McCaughan
.sig under construc
From: John Thingstad
Subject: Re: printing \n
Date: 
Message-ID: <opsfchu0ehpqzri1@mjolner.upc.no>
On Sun, 03 Oct 2004 22:47:52 GMT, Gareth McCaughan  
<················@pobox.com> wrote:

>> (defvar *string-escape-table*
>>    ;; built with LIST and CONS so it's legal to modify it
>>    (list
>>      (cons #\t #\Tab)
>>      (cons #\n #\Newline)
>>      (cons #\r #\Return)))
>
> (For actual use you'd probably want to include the full
> set of C escapes here.)
>

err. yes. you may note that I only implemented a subset of the formatting  
commands as well.
The idea is that I don't really need printf functionality being happy with  
format.
Still I want to leave open the posibility of extending the functionality.
(I thought this would be a nice job for Jim Newton)

>> (set-dispatch-macro-character #\# #\C
>
> Please don't use #C for this; it already has a useful
> meaning.

Forgot about complex numbers.
Scratched my head for a better mnemonic but C as in C strings is the only
one that seems resonable. So I entered a (complex a b) if I found #\(

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Jim Newton
Subject: Re: printing \n
Date: 
Message-ID: <2s8csuF1iav3dU1@uni-berlin.de>
John Thingstad wrote:
> On Sat, 02 Oct 2004 16:54:12 +0200, Jim Newton <·····@rdrop.com> wrote:...

> ~F - like %f

This is great information, thanks.

What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
the field and 3 for the decimal part?

-jim
From: Matthew Danish
Subject: Re: printing \n
Date: 
Message-ID: <877jq83muf.fsf@mapcar.org>
Jim Newton <·····@rdrop.com> writes:
> This is great information, thanks.

Time for you to start reading the Hyperspec, chapter 22.3 Formatted
Output.  http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm

> What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
> the field and 3 for the decimal part?

If I'm not mistaken, it would be "~10,3F".  But you can look this up
for yourself now.

-- 
;; Matthew Danish -- user: mrd domain: cmu.edu
;; OpenPGP public key: C24B6010 on keyring.debian.org
From: Raistlin Magere
Subject: Re: printing \n
Date: 
Message-ID: <cjn0ao$pr7$1@news.ox.ac.uk>
"Jim Newton" <·····@rdrop.com> wrote in message
····················@uni-berlin.de...
> John Thingstad wrote:
> > On Sat, 02 Oct 2004 16:54:12 +0200, Jim Newton <·····@rdrop.com>
wrote:...
>
> > ~F - like %f
>
> This is great information, thanks.
>
> What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
> the field and 3 for the decimal part?
>
> -jim

Not to be rude but have you actually followed the links that John gave you?
I am aware that you edited them out so just to remind you they were :
http://www.lispworks.com/reference/HyperSpec/Body/f_format.htm
http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm

The second one offers informations about all the control sequences of format
including:
*22.3.3 FORMAT Floating-Point Printers*
and to *22.3.3.1 Tilde F: Fixed-Format Floating-Point*
The first paragraph is:

The full form is ~w,d,k,overflowchar,padcharF. The parameter w is the width
of the field to be printed; d is the number of digits to print after the
decimal point; k is a scale factor that defaults to zero.

Followed by a longer description.
From: Thomas A. Russ
Subject: Re: printing \n
Date: 
Message-ID: <ymivfdqa2fd.fsf@sevak.isi.edu>
Jim Newton <·····@rdrop.com> writes:

> What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
> the field and 3 for the decimal part?

Take a look at:

 http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm

The specific answer is probably something like "~10,3F".

I say probably, because I'm not sure what C does if the number is too
big to fit in the field as specified.  Common Lisp (somewhat expectedly)
Does the Right Thing (tm) by expanding the field.  If you want something
closer to FORTRAN's fill with "*" characters on field overflow, then you
need to specify additional arguments to the formatter.

Note that one cool Lisp thing is that you can omit arguments, so to
always get 3 decimal places with the rest of the field just big enough
to hold the answer, you give "~,3F" to format.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Cesar Rabak
Subject: Re: printing \n
Date: 
Message-ID: <4161928F.2090802@acm.org>
Thomas A. Russ escreveu:
> Jim Newton <·····@rdrop.com> writes:
> 
> 
>>What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
>>the field and 3 for the decimal part?
> 
> 
> Take a look at:
> 
>  http://www.lispworks.com/reference/HyperSpec/Body/22_c.htm
> 
> The specific answer is probably something like "~10,3F".
> 
> I say probably, because I'm not sure what C does if the number is too
> big to fit in the field as specified.  Common Lisp (somewhat expectedly)
> Does the Right Thing (tm) by expanding the field.  If you want something

IMHO the judgement of what a "Right Thing" may be depends a little on 
the inteded use:

If you were crafting the above format for a printed output. . .

just my two cents...

--
Cesar Rabak
From: Thomas A. Russ
Subject: Re: printing \n
Date: 
Message-ID: <ymir7od9jqm.fsf@sevak.isi.edu>
Cesar Rabak <······@acm.org> writes:
> Thomas A. Russ escreveu:
> > Jim Newton <·····@rdrop.com> writes:
> > 
> >>What is the FORMAT equivalent of "%10.3f"? allocating 10 spaces for
> >>the field and 3 for the decimal part?
> > 
> > The specific answer is probably something like "~10,3F".
> > 
> > I say probably, because I'm not sure what C does if the number is too
> > big to fit in the field as specified.  Common Lisp (somewhat expectedly)
> > Does the Right Thing (tm) by expanding the field.  If you want something
> 
> IMHO the judgement of what a "Right Thing" may be depends a little on 
> the inteded use:

First off it was a bit of a joke.
Second, I think in this case, it really is the "Right Thing" as the
default behavior -- don't hide anything, and expand as necessary.

> If you were crafting the above format for a printed output. . .

Then you give the format directive the additional arguments and specify
what you want to use to fill the space:

(format nil "~5,3,,'?F" 328490493489) => "?????"






-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Steven Shaw
Subject: Re: printing \n
Date: 
Message-ID: <4163df09_1@news.iprimus.com.au>
Thomas A. Russ wrote:
> Note that one cool Lisp thing is that you can omit arguments, so to
> always get 3 decimal places with the rest of the field just big enough
> to hold the answer, you give "~,3F" to format.

You can do that in C with "%.3f".
From: Pascal Bourguignon
Subject: Re: printing \n
Date: 
Message-ID: <87u0tdp0d8.fsf@thalassa.informatimago.com>
"John Thingstad" <··············@chello.no> writes:

> On Sat, 02 Oct 2004 15:19:06 +0200, Jim Newton <·····@rdrop.com> wrote:
> 
> > in c, perl, python, as well as many other languages printing "\n"
> > prints a carriage return.

For wat definition of "print"?
 
> Not exactly, \n advances to the next line. (in Lisp #\newline)
> 
> on Mac \n gives carriage return
> on Unix \n gives line feed
> under Windows \n gives line feed followed by carriage return

Note however that on all these systems, printing a new line always
produces a CR LF sequence on a line printer or terminal.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we.
From: Joel Ray Holveck
Subject: Re: printing \n
Date: 
Message-ID: <87fz4xylrs.fsf@thor.piquan.org>
>> on Mac \n gives carriage return
>> on Unix \n gives line feed
>> under Windows \n gives line feed followed by carriage return
> Note however that on all these systems, printing a new line always
> produces a CR LF sequence on a line printer or terminal.

Uhm.... When was the last time you saw a TTY on Windows?  Are you
talking about using CTTY?

Or for that matter, on a pre-OS X Mac?  (Is OS X's newline convention
still the same, or did it go the Unix way?)

On Unix, the terminal driver translates a linefeed to a CRLF, if ONLCR
is set, of course.  This even happens when you're printing to devices
that aren't really terminals, such as xterms or telnet sessions.  But
I don't know of any layer on the Mac or Windows that supports that
kind of thing.

Cheers,
joelh

-- 
Joel Ray Holveck - ·····@piquan.org
   Fourth law of programming:
   Anything that can go wrong wi
sendmail: segmentation violation - core dumped
From: Pascal Bourguignon
Subject: Re: printing \n
Date: 
Message-ID: <87d600pyk3.fsf@thalassa.informatimago.com>
Joel Ray Holveck <·····@piquan.org> writes:

> >> on Mac \n gives carriage return
> >> on Unix \n gives line feed
> >> under Windows \n gives line feed followed by carriage return
> > Note however that on all these systems, printing a new line always
> > produces a CR LF sequence on a line printer or terminal.
> 
> Uhm.... When was the last time you saw a TTY on Windows?  

Every time I have to use MS Windows. I only use  MS Windows thru the
MS-DOS box in which I launch cygwin...

> Are you talking about using CTTY?
> 
> Or for that matter, on a pre-OS X Mac?  (Is OS X's newline convention
> still the same, or did it go the Unix way?)
> 
> On Unix, the terminal driver translates a linefeed to a CRLF, if ONLCR
> is set, of course.  This even happens when you're printing to devices
> that aren't really terminals, such as xterms or telnet sessions.  But
> I don't know of any layer on the Mac or Windows that supports that
> kind of thing.

I did not expand on MacOS, but deep down MacOS (not MacOSX), there is
code to map CR from and to CRLF or LF.  Read Inside Macintosh I for
the details.  Of course, it's not often activated...

All right, a new line is never sent to a bitmap screen as a control
code byte sequence.  When a new line appears in the data flow,
following characters are drawn slightly more on the left and slightly
more downward than othewise (at least in roman scripts).  But the
sending of CR-LF still occurs when the destination is a line printer
(or a laser or ink jet printer used in line printer emulation).

Now, perhaps emacs, vi and other ncurses instead send CUP, or NEL, or
CNL, or even IL, when they must display a new line on a terminal, and
only rarely use CR-LF.

My point is that one should not confuse the control sequence sent to a
devices or the graphic primitives used to draw on a bitmap in order to
present a line under another one,  and the representation of a
sequence of line in files or character streams.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

To vote Democrat or Republican, it's like changing of cabin in the Titanic.
From: Thomas A. Russ
Subject: Re: printing \n
Date: 
Message-ID: <ymiu0taa2bi.fsf@sevak.isi.edu>
Joel Ray Holveck <·····@piquan.org> writes:

> Or for that matter, on a pre-OS X Mac?  (Is OS X's newline convention
> still the same, or did it go the Unix way?)

Both are in use.  The standard unix tools don't like #\Return, though.

Just to make matters even more confusing, MCL by default uses #\Return,
and openmcl uses #\Linefeed.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Raffael Cavallaro
Subject: Re: printing \n
Date: 
Message-ID: <2004100500382116807%raffaelcavallaro@pasdespamsilvousplaitdotmaccom>
On 2004-10-02 15:15:19 -0400, Joel Ray Holveck <·····@piquan.org> said:

> Or for that matter, on a pre-OS X Mac?  (Is OS X's newline convention
> still the same, or did it go the Unix way?)

It actually uses both, depending on application (e.g., Applescript 
still uses Mac style paths and line breaks while Terminal uses Unix 
conventions), and user preferences (e.g., BBEdit allows users to set 
line break defaults and on a per file basis).
From: Rob Warnock
Subject: Re: printing \n
Date: 
Message-ID: <GMydnVg-LMuypvPcRVn-og@speakeasy.net>
John Thingstad <··············@chello.no> wrote:
+---------------
| under Windows \n gives line feed followed by carriage return
+---------------

I think you meant carriage return followed by line feed (a.k.a. CR-LF).


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607