another format question

  • Follow


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?

0
Reply andrew.polonsky (11) 11/22/2007 2:52:52 PM

Thank you!
That does exactly what I want.

On Nov 22, 5:12 pm, Petter Gustad <newsmailco...@gustad.com> wrote:
> andrew.polon...@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?

0
Reply andrew.polonsky (11) 11/22/2007 3:26:06 PM


andrew.polonsky@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?
0
Reply newsmailcomp6 (330) 11/22/2007 4:12:03 PM

> From: andrew.polon...@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.
0
Reply rem642b (595) 11/23/2007 7:30:58 PM

3 Replies
41 Views

(page loaded in 0.066 seconds)


Reply: