Hi,
how do I put a source-level constant inside a complicated format
control string?
I see one solution using macro + indirection, like
(defmacro my-const () "~3,'0D")
...
(defun print-stuff (n)
(format t "...variable # ·@?..." (my-const) n)) )
...
Then
(print-stuff 39) -> ...variable # 039...
but if we have
(defmacro my-const () "~9,'0D")
then
(print-stuff 39) -> ...variable # 000000039...
However, this way I can't insert it into a format loop unless I put
the whole string into my-const.
How do I make a macro which takes an integer and produces a string
containing that integer?
···············@gmail.com writes:
> (defmacro my-const () "~3,'0D")
> ...
> (defun print-stuff (n)
> (format t "...variable # ·@?..." (my-const) n)) )
I think what you are trying to do can be archived with:
(format t "~V,'0D" 3 39)
Petter
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Thank you!
That does exactly what I want.
On Nov 22, 5:12 pm, Petter Gustad <·············@gustad.com> wrote:
> ···············@gmail.com writes:
> > (defmacro my-const () "~3,'0D")
> > ...
> > (defun print-stuff (n)
> > (format t "...variable # ·@?..." (my-const) n)) )
>
> I think what you are trying to do can be archived with:
>
> (format t "~V,'0D" 3 39)
>
> Petter
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is top-posting such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: another format question
Date:
Message-ID: <rem-2007nov23-001@yahoo.com>
> From: ···············@gmail.com
> how do I put a source-level constant inside a complicated format
> control string?
Lisp provides many different ways to accomplish the same task. What
is best practice is a matter of opinion. When working for a boss,
you do it the way your boss prefers. When working for yourself, you
do it whichever way you personally like best. Below is just *my*
personal preference. Consider it with all the other suggestions.
Whenever I need an object which isn't lexically verbatim in my
source code, I write a function to build it. In this case you want
a format string which is constructed from pieces rather than
written verbatim into your source. So in a case like this I'd write
a function called something like MAKE-FORMAT-STRING.
Then for the FORMAT call, I'd write (FORMAT T (MAKE-FORMAT-STRING ...) ...)
Of course I said "like", which means I'd give it a more specific
name. For example if it was a format string for printing column headings,
whose exact spacing depended on the widths of the various columns,
then it might be called MAKE-FORMAT-STRING-FOR-COLUMN-HEADINGS,
which might take one parameter which was a list of column widths
(including extra space between columns) and another parameter which
was a list of the corresponding column titles. A corresponding
function would be MAKE-FORMAT-STRING-FOR-ROW which would take just
the list of column widths, and whose output would include ~nD
directives where n is the corresponding column width. Usage would then be
(FORMAT T (MAKE-FORMAT-STRING-FOR-COLUMN-HEADINGS colsizes colnames))
(APPLY #'FORMAT T (MAKE-FORMAT-STRING-FOR-ROW colsizes) onerowvalues)
I haven't tested that, just composing it on the fly, hope I got it correct.
If the format string (for column headings above) is never going to
change during the execution of your application, you might
DEFPARAMETER it, but that's such a trivial savings of CPU time at
cost in flexibility that I don't really recommend it.
> How do I make a macro which takes an integer and produces a string
> containing that integer?
Why do you think you need a macro? Why isn't an ordinary function good enough?
(defun make-formatd-string (n)
(format nil "~~~dD" n))
(make-formatd-string 42) ==> "~42D"
Isn't that already good enough for your needs?
IMO the purpose of a macro is source-code (form actually)
transformation, from some form that violates the general rule that
every element in a form after the first is recursively evaluated,
to some other form that satisfies that general rule.
For example, if you want to transform this form:
(my-al foo (compute-foo) bar (compute-bar))
to this form:
(list (cons 'foo (compute-foo)) (cons 'bar (compute-bar)))
you would define my-al as a macro.
I don't think you need to do this for your application, but it's your call.