[comp.lang.ada] integer'image

ae@sei.cmu.edu (Arthur Evans) (01/19/91)

Michael Feldman (mfeldman@seas.gwu.edu) asks about the leading space in
INTEGER'IMAGE.

An Ada 9X Revision Request asking to eliminate this space was rejected
by the Requirements Team.  I don't speak for the Team.  However, I've
always assumed that the space was for symmetry with negative numbers.
That is, +N and -N always have a 'image of the same width.

Yes, getting rid of that space is a bother.  Better is to instantiate
Integer_IO.

Art Evans
Software Engineering Institute
Carnegie Mellon University

mfeldman@seas.gwu.edu (Michael Feldman) (01/19/91)

In article <10140@as0c.sei.cmu.edu> ae@sei.cmu.edu (Arthur Evans) writes:

>An Ada 9X Revision Request asking to eliminate this space was rejected
>by the Requirements Team.  I don't speak for the Team.  However, I've
>always assumed that the space was for symmetry with negative numbers.
>That is, +N and -N always have a 'image of the same width.
This is utter nonsense. Why not give me a width parameter such as I have in
Integer_IO already? I've always envisioned the 'image and 'value attributes
as, inter alia, a baseline of operations with which to WRITE I/O routines,
equivalent to the atoi and itoa calls in the C library. I realize you don't
speak for the team, so this flame is not aimed at you, but flame it is.

If I can't get a flush-left string out of 'image, it's virtually useless.
And if 'image and 'value aren't symmetric, why not? 'value reads past
whitespace; why should 'image give me gratuitous whitespace? Look at C.
Let me do my own padding, guys. The nonuniformity in attributes is
utterly maddening in Ada. I'll give more examples sometime.
>
>Yes, getting rid of that space is a bother.  Better is to instantiate
>Integer_IO.
Yeah, right. So what good is 'image? Any comments from Team members?

Mike Feldman

g_harrison@vger.nsu.edu ((George C. Harrison) Norfolk State University) (01/19/91)

In article <2563@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes:
> In answering the question about cursor control, George Harrison and I used
> 2 different techniques to get the row and column values sent to the 
> terminal. I assumed an Integer_IO instantiation; he (probably rightly) did
> not. But all this makes me wonder why on earth Integer'Image should
> decide to prepend a blank to the numeric string. To delete this blank,
> just to get a left-adjusted numeric string, requires overkill code of
> one kind or another, as George's solution makes abdundantly clear.
> 

That's exactly right.  Do-While Jones in his _Ada in Action_ complains about
the same thing.  He then develops a package that even does essentially
Float'Image, etc.  I highly recommend the book for good reading with his [very]
dry sense of humor.  

I would like to hear if anyone feels (like me) that this book is somewhat of a
real treasure.  -- or otherwise.

George....

--------------------------------------------------------------------------
-- George C. Harrison -------------- || -- Overworked, Underpaid, --------
---|| Professor of Computer Science  || -- Unappreciated, but enjoying ---
---|| Norfolk State University, ---- || -- it all. -----------------------
---|| 2401 Corprew Avenue, Norfolk, Virginia 23504 -----------------------
---|| INTERNET:  g_harrison@vger.nsu.edu ---------------------------------
-- ||                 Pray for Peace and a Quick End 

rosen@meduse.enst.fr (Jean Pierre Rosen) (01/19/91)

Answer to your concern is simple: 'IMAGE is not intended for output.
As you point out, PUT is very convenient, EVEN for converting integers
to strings, thanks to the nice PUT to string.
Using 'IMAGE has other drawbacks: if you have a bounded line length,
PUT(INTEGER'IMAGE(X)) will split the number in two accross line boundary,
making it impossible to read later on, while PUT(X) will issue a
new-line correctly.
What is the advantage of using 'IMAGE? it "saves" one instantiation.
I don't see any advantage in "saving" that kind of instantiations. It
is just a bad trick that people use to often.

To summerize: if you want to drive a screw with a hammer, don't complain
the hammer's head is too large: use the right tool.

hoysch@ucselx.sdsu.edu ( Hoysch) (01/20/91)

	I think a big thing is being made out of something that is not very
hard to do.  For example INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST) will
do it or a very simple routine if this is too hard on the eyes.  That 
space, as has been pointed out, is often nice to have to offset the '-'
of negative numbers.

			Dan "Hoysch" Heuschele	

mfeldman@seas.gwu.edu (Michael Feldman) (01/21/91)

In article <1991Jan20.025451.29808@ucselx.sdsu.edu> hoysch@ucselx.sdsu.edu (      Hoysch) writes:
>
>	I think a big thing is being made out of something that is not very
>hard to do.  For example INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST) will
>do it or a very simple routine if this is too hard on the eyes.  That 
>space, as has been pointed out, is often nice to have to offset the '-'
>of negative numbers.
>
Well, that'll work if I is positive. Otherwise it'll delete the -. So in
any case a test is needed to ascertain the sign. I'd prefer for 'image to
give me what's there, not add extra stuff that I have to delete.

One purpose for the 'image and 'value attributes, it seems to me, is to aid
in _writing_ I/O packages in lieu of (or on top of) Text_IO. The extra
blank just adds an extra bit of aggravation. I'd be happier with it if it
incorporated a general "pad" parameter, but it doesn't.

Recall that the thing that started this thread was developing a terminal-
control package that could easily ship ASCII sequences to a terminal to do
cursor movement, etc. There is no doubt that what you wrote is correct, for
positive values. I was complaining about the arbitrary lack of uniformity
in attributes, and this was the latest. I claim it's much easier to _add_
a blank to get the symmetry between positive and negative numbers than to
_delete_ the blank as you did. Ada9x is looking into the whole problem of
"edit-directed output", which will, if they really do it well, solve a lot
of these problems in a much more general way. Meanwhile, I don't like the
asymmetry between integer PUT and integer'image; in the former I can control
the width precisely because they thought to give me a parameter; in the latter
I cannot, and they decided to stick me with a gratuitous blank. I don't
think gratuitous padding is very user-friendly. The early subset compilers,
by the way, didn't add the blank - it got stuck in there somewhere between
the '80 and '83 versions of the standard, and I think they blew it.

Mike

jcallen@Encore.COM (Jerry Callen) (01/21/91)

In article <1991Jan20.025451.29808@ucselx.sdsu.edu> hoysch@ucselx.sdsu.edu (      Hoysch) writes:
>
>	I think a big thing is being made out of something that is not very
>hard to do.  For example INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST) will
>do it or a very simple routine if this is too hard on the eyes.

It will also chop off the minus sign if the value happens to be negative.
Furthermore, the generated code will almost certainly gag a maggot. 

Another suggestion has been instantiating integer_io and using put to a
a string; fine, but now you get to carry around the baggage of the entire
integer_io package (which may or may not be significant, depending upon
the compiler, linker, etc.).

I hate the $#@ leading space. I can usually just live with it. Nearly all
of my use of integer'IMAGE is in debugging code anyway...

-- Jerry Callen
   jcallen@encore.com

case@shamash.cdc.com (Steven V. Case) (01/22/91)

In article <13874@encore.Encore.COM>, jcallen@Encore.COM (Jerry Callen) writes:
> In article <1991Jan20.025451.29808@ucselx.sdsu.edu> hoysch@ucselx.sdsu.edu (      Hoysch) writes:
> >
> >	I think a big thing is being made out of something that is not very
> >hard to do.  For example INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST) will
> >do it or a very simple routine if this is too hard on the eyes.
> 
> It will also chop off the minus sign if the value happens to be negative.
> Furthermore, the generated code will almost certainly gag a maggot. 

I have encountered this situation frequently enough that I work around it
by calling a subprogram to strip leading spaces.  I suspect that most of you
have some sort of string manipulation package that you have either 
developed or purchased.  I made sure that mine has support for removing 
leading and trailing spaces (in addition to other operations).  Then when I
want to get rid of the trailing space, I don't have to embed statements
like INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST), but can use a statement
such as REMOVE_LEADING_SPACES(FROM => INTEGER'IMAGE(I)).  This is probably
more readable, therefore it won't 'gag a maggot'.  I suspect this is the
general idea that Mr. Hoysch was suggesting when he said 'or a very simple
routine if this is too hard on the eyes.'

-- 
  ____  ____        Steve Case - HQG526           email: case@shamash.cdc.com
 / ___||___ \       Control Data Corporation      AT&T : (612) 853-3345
| |___  ___| |      3101 East 80th Street                 
 \____||____/       Bloomington, MN 55425

jcallen@Encore.COM (Jerry Callen) (01/22/91)

In article <29979@shamash.cdc.com> case@shamash.cdc.com (Steven V. Case) writes:
>[various quoted material deleted; essentially, a routine to stripped
> leading spaces can be used to trim the leading blank from the
> result of integer'IMAGE on positive integers. Then...]
>
>... I don't have to embed statements
>like INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST), but can use a statement
>such as REMOVE_LEADING_SPACES(FROM => INTEGER'IMAGE(I)).  This is probably
>more readable, therefore it won't 'gag a maggot'.  I suspect this is the
>general idea that Mr. Hoysch was suggesting when he said 'or a very simple
>routine if this is too hard on the eyes.'

I wasn't complaining about Ada code readability; sure you can hide the
ugliness of INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST) behind a procedure
call. I meant that the _code out of the compiler_ will be hideous; two
calls to integer'IMAGE, one to 'LAST, then a slicing operation. Yuch.
It's this sort of thing that makes C programmers look at Ada and throw
up their hands in despair.

[Don asbestos suit...]

I hate to admit it, but I'd really love an Ada equivalent of printf that
takes some nice formatting string and some variables to be printed and
then does the right thing. Occasionally (NOT very often...) strong typing
is a real pain in the buns.

-- Jerry Callen
   jcallen@encore.com

P.S. No, I'm not a C bigot; in fact, most C code is hideous enough to, well,
	 to gag a maggot. :-)

mfeldman@seas.gwu.edu (Michael Feldman) (01/23/91)

In article <29979@shamash.cdc.com> case@shamash.cdc.com (Steven V. Case) writes:
>I have encountered this situation frequently enough that I work around it
>by calling a subprogram to strip leading spaces.  I suspect that most of you
>have some sort of string manipulation package that you have either 
>developed or purchased.  I made sure that mine has support for removing 
>leading and trailing spaces (in addition to other operations).  Then when I
>want to get rid of the trailing space, I don't have to embed statements
>like INTEGER'IMAGE(I)(2..INTEGER'IMAGE(I)'LAST), but can use a statement
>such as REMOVE_LEADING_SPACES(FROM => INTEGER'IMAGE(I)).  This is probably
>more readable, therefore it won't 'gag a maggot'.  I suspect this is the
>general idea that Mr. Hoysch was suggesting when he said 'or a very simple
>routine if this is too hard on the eyes.'

Humbug! I hope the Ada9x team is reading this thread, to see the sort of
totally unnecessary grief is caused by what IMHO is a foolish nonuniformity
that's got to be nearly trivial to fix.

Since 'image will need to call some runtime routine to convert integer to
string, I suggest that 'image carry a second parameter, just like the
Put routines do, to control the width. So as not to disable existing programs,
default it to whatever is currently used. A Width parameter is really just the
right way, it seems to me, since then a value of 1 (or 0) says "give me exactly
the right number of characters" and a greater value suggests padding if
necessary.

Even better, give us a third parameter to control whether padding is on the 
left or on the right. Make Text_IO conform, too.

Attributes are one example of a _really neat_ thing in Ada that works 
intuitively about 90% of the time, and the 10% nonuniformity makes the
good stuff a bear to learn and causes annoyances like the above to work
around the nonuniformities.

I know, I know. I missed my shot to submit this as a revision request. I
assume someone else did, though. I'll check in my archive of RRs.

Mike Feldman

pattis@cs.washington.edu (Richard Pattis) (01/23/91)

And add a parameter that allows padding to be a ' ' or '0' or any other
aribtrary character. For printing times, I want 12:05:07.

I think what this series of posts finally has lead to the conclusion
that everyone wants slightly different variants of the  INTEGER => STRING
conversion function.  All can be written easily, given INTEGER'IMAGE; yes,
some might be written a bit more easily if the ' ' wasn't added at the
front of non-negative numbers (but I don't claim to have any arguments
for or against).

This "problem" disappears one abstraction level up.  I can't think of
the last time I used INTEGER'IMAGE in my code (I mostly use an overloaded
& to catenate strings and numeric values, or when special formatting is
required, my own formatting routines).

I don't care what INTEGER'IMAGE does; it might be useful to have a nice
package of INTEGER => STRING functions, including conversions to roman
numerals and english: "XXVII" and "TWENTY SEVEN".

Let's get back to convincing Ada compiler developers that they can all
get rich by selling cheaply priced student compilers (and then make even
more money by selling these students special packages that perform such
conversions).

Rich Pattis

mfeldman@seas.gwu.edu (Michael Feldman) (01/24/91)

In article <14613@june.cs.washington.edu> pattis@cs.washington.edu (Richard Pattis) writes:
>
>Let's get back to convincing Ada compiler developers that they can all
>get rich by selling cheaply priced student compilers (and then make even
>more money by selling these students special packages that perform such
>conversions).

You're right, Rich. I've been operating on a couple of levels:

1. convince the Ada community to find nice, lucrative ways of expanding the
   Ada market, especially by hooking students and teachers on Ada, which we
   all know will have good long-term effects, as was the case with nearly
   every other language.

2. make sure that the Ada9x folks do the right thing, especially when it
   comes to little, "stupid," nonuniformities in the language that make it
   hard to learn and teach - of which the attribute system is the best
   example. I believe these little oversights can be _easily_ rectified
   given the will to do so, with little compilation or runtime penalty.
   Ada9x will be much more salable to engineers and - especially - to
   information systems folks - if more attention is paid to stuff like
   this. There are lots of little places where Ada gives with one hand
   and takes with the other, and there don't seem to be good justifications,
   just human frailty in the design. These can be fixed, given the will.

OK, enough.

Mike

west@widgit.enet.dec.com (Jim West (Stealth Contractor)) (01/28/91)

In article <2563@sparko.gwu.edu>,
mfeldman@seas.gwu.edu (Michael Feldman) writes...

>In answering the question about cursor control, George Harrison and I used
>2 different techniques to get the row and column values sent to the 
>terminal. I assumed an Integer_IO instantiation; he (probably rightly) did
>not. But all this makes me wonder why on earth Integer'Image should
>decide to prepend a blank to the numeric string. To delete this blank,
>just to get a left-adjusted numeric string, requires overkill code of
>one kind or another, as George's solution makes abdundantly clear.
> 
>The Put operations for integers, enumerations, etc., allow you to control
>the field width exactly; you can right-adjust or you can display the literal
>flush-left. Why should the attribute not do the same? I HATE these stupid
>little counterintuitive surprises in Ada, much as I like the language in
>general. Drives students absolutely up the wall.
> 
>The Ada9x Requirements do not give any specifics in the "little things
>to clean up" category, but I surely hope the Mapping/Revision team will
>give some attention to making the whole attribute system more uniform and
>intuitive. I can give examples if anyone would like. 
>Any response from anyone on the team?
> 

  The blank is for the sign field.  Positive numbers are displayed without
the '+' sign whereas negative numbers are displayed with the '-' sign.

  If you were printing numbers that are both positive and negative then
formatting becomes easier with respect to the sign field.

  The following program and output demonstrates this.


with
	text_io,
	integer_text_io; -- preinstanciation of text_io.integer_io(integer)

procedure INT_TEST is

  x : integer := 3;
  y : integer := -5;

begin --INT_TEST

  text_io.put_line ("Here is the test...");
  text_io.put_line ("->" & integer'image(x) & "<-");
  text_io.put_line ("->" & integer'image(y) & "<-");

end INT_TEST;


Here is the test...
-> 3<-
->-5<-

  I don't disagree with you when it comes to just positive numbers and you
wish to display them without this leading blank.

----------------------------------------------------------------------
 Jim West                      |  The Schainker Converse
 west@widgit.enet.dec.com      |  to Hoare's Law :
                               |
 These are my opinions.        |   Inside every small problem
 Digital has no idea           |     is a larger problem struggling
 what I'm  saying.             |       to get out.
----------------------------------------------------------------------

mfeldman@seas.gwu.edu (Michael Feldman) (01/28/91)

In article <2390@shodha.enet.dec.com> west@widgit.enet.dec.com (Jim West (Stealth Contractor)) writes:
>
>  The blank is for the sign field.  Positive numbers are displayed without
>the '+' sign whereas negative numbers are displayed with the '-' sign.
>
>  If you were printing numbers that are both positive and negative then
>formatting becomes easier with respect to the sign field.
>
I know I told Rich Pattis I'd stop posting this thread to the net, but
I can't let this go by without comment. I know the idea is to get the symmetry 
with negative numbers. However, it's MUCH easier to prepend the blank if I 
want it than to strip it off if I don't. Specifically, the string form is
nice if you're writing terminal drivers (ANSI control, etc.), which only
want to see digits, no spaces. And I'd rather not waste a whole Integer_IO
instance just on that, so 'image is the nice way to go. Indeed, I thought
that was _just_ was integer'image was intended for!

I claim that

  IF X > 0 THEN
    Text_IO.Put(' ' & Integer'Image(X);
  ELSE
    Text_IO.Put(Integer'Image(X));
  END IF;

is far easier and cleaner than any of the kludges I've seen to strip the
blank. If one wants to avoid burying too many string concatenations
(storage allocation problems, it is alleged), then

  IF X > 0 THEN
    Text_IO.Put(' ');
  END IF;
  Text_IO.Put(Integer'Image(X));

fills the bill and is cleaner still. Compare that with all the junk that's
come over the net about how to throw the blank away!

I promise to finally shut up on this issue; if Ada9x hasn't gotten the message
by now, they never will.

Mike

g_harrison@vger.nsu.edu ((George C. Harrison) Norfolk State University) (01/29/91)

In article <2638@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes:
> In article <2390@shodha.enet.dec.com> west@widgit.enet.dec.com (Jim West (Stealth Contractor)) writes:
>>
>>  The blank is for the sign field.  Positive numbers are displayed without
>>the '+' sign whereas negative numbers are displayed with the '-' sign.
>>
Ya... we know that!

etc.
> instance just on that, so 'image is the nice way to go. Indeed, I thought
> that was _just_ was integer'image was intended for!

The problem really is the formatting of enumerated elements, integers, and
[ideally] floats in the middle of string expressions.

I am tired of writing

PUT("The temperature at the");
MYINTEGER_IO.PUT(N,5);
PUT(" hour is");
MYFLOAT_IO.PUT(TEMPERATURE,7,2);
PUT(" ");
MYTEMPERATURE_TYPE_IO.PUT(FAHRENHEIT);
NEW_LINE;

etc.

> if Ada9x hasn't gotten the message by now, they never will.
> 
> Mike

Ada9x-folks have to admit that just because there is a "work-around" doesn't 
mean that there are parts of this great programming language that introduce 
some unnecessary complications to do some very common things.  

-- George C. Harrison -------------- || -- My opinions and observations --
---|| Professor of Computer Science  || -- Only. -------------------------
---|| Norfolk State University, ---- || ----------- Pray for Peace -------
---|| 2401 Corprew Avenue, Norfolk, Virginia 23504 -----------------------
---|| INTERNET:  g_harrison@vger.nsu.edu ---------------------------------

Do we really want to turn off the potential Ada community or do we want them to 
enjoy the language and most of us do?  

edwards@rutabaga.cis.ohio-state.edu (stephen edwards) (01/30/91)

In article <557.27a476f2@vger.nsu.edu> g_harrison@vger.nsu.edu ((George C. Harrison) Norfolk State University) writes:
[ ... stuff about INTEGER'IMAGE deleted ... ]
>
>The problem really is the formatting of enumerated elements, integers, and
>[ideally] floats in the middle of string expressions.
>
>I am tired of writing
>
>PUT("The temperature at the");
>MYINTEGER_IO.PUT(N,5);
>PUT(" hour is");
>MYFLOAT_IO.PUT(TEMPERATURE,7,2);
>PUT(" ");
>MYTEMPERATURE_TYPE_IO.PUT(FAHRENHEIT);
>NEW_LINE;
>

Well, believe it or not, there are very trivial ways to do this easily.
Imagine being able to write the following magical expression:

    Put_Line("The temperature at the " & N & " hour is " &
    	     TEMPERATURE & " " & FAHRENHEIT);

Well, you can do this easily in Ada, albeit with the addition of a few
function definitions over and above those provided in Text_IO.  Of course,
you can wrap those in packages (generic ones, even) to use them over and
over--so you'll never have to write horrible, complicated output expressions
again! :-) :-) :-)

Of course, those who hate overloading or _use_ clauses, especially if they
are used together, will jump all over you.  However, it seems the code
is much more readable in the above example (not to mention easier to write,
and easier to maintain).  There _are_ times when these capabilities can
be very useful.

Also notice that none of these facilities require any changes to the
current Text_IO spec or implementation.  All can be layered right on
top of the existing package in a completely portable manner.

Note: actual definitions for the various instances of "&" in the above
example are left as an exercise for the reader.  For extra credit, think
about how one would extend such definitions to support the extra formatting
a fully general system might support (e.g., MyInteger_IO.Put(n,5); ...
MyFloat_IO.Put(temperature, 7, 2); ... etc., in the current Text_IO).



			-- Steve

Stephen Edwards					U.S. mail: 372 Jones Tower
e-mail    : edwards@cis.ohio-state.edu	           	   101 Curl Drive
home phone: (614)-293-0842			 	   Columbus, OH  43210