comp.lang.ada
 help / color / mirror / Atom feed
* private type discriminants ignored?
@ 1998-04-24  0:00 ` Jay Sachs
  1998-04-24  0:00   ` Joel VanLaven
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jay Sachs @ 1998-04-24  0:00 UTC (permalink / raw)




In a series of successive refinements of a stack package, I've
declared:

    package Stacks4 is
       type Stack(Size : Integer := 100) is private;
       -- this version:
       --      type Stack is private;
       -- also exhibits the same behavior

       procedure Push(S : in out Stack; X : Integer);
       procedure Pop(S : in out Stack; X : out Integer);
       function Empty(S : in Stack) return Boolean;
       Stack_Overflow : exception;
       Stack_Underflow : exception;

    private
       type stackrep is array(Integer range <>) of Integer;
       type Stack(Size : Integer := 100) is record 
	  Top : Natural := 0;
	  Rep : stackrep(1..Size);
       end record;
    end Stacks4;

I get warnings (from gnat 3.10) saying that I may get a storage_error
by creating a variable of type stack.  I do in fact get such an error
if I declare

  s : Stacks4.Stack;

and use it like:

  Stacks4.push(s,3);

However, supplying the initialization as in

  s2 : Stacks4.Stack(75);

allows

  Stacks4.push(s2,3);

with no error.  What is the reason that the default initialization
seems to be ignored in the discriminant for the private type?

-Jay




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
  1998-04-24  0:00 ` Jay Sachs
@ 1998-04-24  0:00   ` Joel VanLaven
       [not found]   ` <Es3A4J.Ion@world.std.com>
  1998-04-30  0:00   ` Anonymous
  2 siblings, 0 replies; 9+ messages in thread
From: Joel VanLaven @ 1998-04-24  0:00 UTC (permalink / raw)



Jay Sachs <sachs@cs.williams.edu> wrote:
[message trimmed for content]
:        type Stack(Size : Integer := 100) is record 
: 	  Top : Natural := 0;
: 	  Rep : stackrep(1..Size);
:        end record;

: I get warnings (from gnat 3.10) saying that I may get a storage_error
: by creating a variable of type stack.  I do in fact get such an error
: if I declare

:   s : Stacks4.Stack;

: However, supplying the initialization as in

:   s2 : Stacks4.Stack(75);

: with no error.  What is the reason that the default initialization
: seems to be ignored in the discriminant for the private type?

Default initializations of the type you are using have a very special
meaning in Ada.  They indicate that the constraint can be changed.  Objects
declared like s are sometimes referred to as "mutable" meaning that one can
assign to them a value with a constraint other than 100.  Essentially,
there are three ways objects get their constriant:

explicitly (forever constained to that value like 75 above)
by initialization (forever constained like a : string := "abcd" will
                   always have length 4)

by default (mutable, can be changed, un-constrained like s above)

Many (most, all?) compilers implement this by allocating (I'm using that
term loosely) the maximum possible space needed to represent an object of
the type with any constraint.  So, s is of size on the order of magnitude
of integer'last.  Not good.  If size was of some type that ranged from
1 to 200 GNAT would likely make s of size on the order of 200 and 
everything would be fine.

I don't think you really want mutable objects here.  It can be useful
but is one of the trickier and fancier features in Ada, and I don't think
it is what you are looking for.

-- Joel VanLaven
-- (I just happen to work for OC Systems)




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
       [not found]   ` <Es3A4J.Ion@world.std.com>
@ 1998-04-28  0:00     ` Samuel T. Harris
  1998-04-28  0:00       ` Patrick D. Rogers
  0 siblings, 1 reply; 9+ messages in thread
From: Samuel T. Harris @ 1998-04-28  0:00 UTC (permalink / raw)



Robert A Duff wrote:
> 
> In article <rz84szje1ol.fsf@cs.williams.edu>,
> Jay Sachs  <sachs@cs.williams.edu> wrote:
> >       type Stack(Size : Integer := 100) is private;
> 
> >...  What is the reason that the default initialization
> >seems to be ignored in the discriminant for the private type?
> 
> The default isn't being ignored; Size is being correctly initialized to
> 100.  However, the mere presence of a default means that the
> discriminant can change.  That's confusing, and is a language design
> flaw, IMHO.  There should have been a separate keyword or some other
> separate syntax to mean "the discrim might change".  But as it is in
> Ada, an unconstrained variable of type Stack can later have a discrim of
> Integer'Last, even though it defaults initially to 100.  And many
> compilers take the (quite reasonable) attitude that implicit heap
> allocation is evil, so they allocate the maximum possible size for these
> things.  And in this case, that's enormous, and will typically raise
> Storage_Error; hence the warning.

Not entirely accurate. The mere presense of the default value does
not mean the discriminant can change. It depends on how objects
are declared.

The discriminant can only change if the subtype indication used
to declare an object does not specify its value. Such as ...

my_stack : stack;

The subtype indication "stack" provides no value for the
discriminant so the default is used. Because the subtype
indication does not "lock" down the value, the discriminant
can indeed change when the whole object is assigned.
The discriminant cannot change by itself as in ...

my_stack.size := 1000; -- Compilation error.

Because the discriminant can change, I expect a compiler to allocate
an amount of memory needed for the worst size case. 

However, if I define ...

your_stack : stack(100);

... then the discriminant cannot change, even when assigne the
entire object, and I do not expect the compiler to allocate
to worst case amount of memory. I expect it to allocate only
enough memory for a stack of 100 elements.

In any event, I treat Robert Duff's advice below as gospel.
All types should be constrainted according to their requirements.
This lets the compiler catch many potential problems.

> 
> If you want stacks that can range from 0 to 1000, with a default of 100,
> try:
> 
>     type Stack_Length is range 0..1000;
>     type Stack (Length: Stack_Length := 100) is ...
> 
> But this will allocate 1000 elements, when perhaps only 100 are needed.
> If you really want the size to change, but you want the amount allocated
> to reflect the current size, you'll need to use access types.  If you
> just want a default of 100, but never want the size to change, don't use
> defaults:
> 
>     type Stack(Length: Natural) is ...
>     subtype Default_Stack is Stack(Length => 100);
>     X, Y: Default_Stack;
>     Huge_Stack: Stack(Length => 100_000);
> 
> - Bob
> --
> Change robert to bob to get my real email address.  Sorry.

-- 
Samuel T. Harris, Principal Engineer
Raytheon Training Incorporated
"If you can make it, We can fake it!"




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
  1998-04-28  0:00     ` Samuel T. Harris
@ 1998-04-28  0:00       ` Patrick D. Rogers
  1998-04-28  0:00         ` Samuel T. Harris
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick D. Rogers @ 1998-04-28  0:00 UTC (permalink / raw)



Samuel T. Harris wrote:
> 
> Robert A Duff wrote:
> >
> > In article <rz84szje1ol.fsf@cs.williams.edu>,
> > Jay Sachs  <sachs@cs.williams.edu> wrote:
> > >       type Stack(Size : Integer := 100) is private;
> >
> > >...  What is the reason that the default initialization
> > >seems to be ignored in the discriminant for the private type?
> >
> > The default isn't being ignored; Size is being correctly initialized to
> > 100.  However, the mere presence of a default means that the
> > discriminant can change.  That's confusing, and is a language design
> > flaw, IMHO.  There should have been a separate keyword or some other
> > separate syntax to mean "the discrim might change".  But as it is in
> > Ada, an unconstrained variable of type Stack can later have a discrim of
> > Integer'Last, even though it defaults initially to 100.  And many
> > compilers take the (quite reasonable) attitude that implicit heap
> > allocation is evil, so they allocate the maximum possible size for these
> > things.  And in this case, that's enormous, and will typically raise
> > Storage_Error; hence the warning.
> 
> Not entirely accurate. The mere presense of the default value does
> not mean the discriminant can change. It depends on how objects
> are declared.


Sam,

Since we are in pedantic mode, :) Bob said "... unconstrained variable
...", so he is indeed entirely accurate.

:) 


--pat

Patrick Rogers




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
  1998-04-28  0:00       ` Patrick D. Rogers
@ 1998-04-28  0:00         ` Samuel T. Harris
  0 siblings, 0 replies; 9+ messages in thread
From: Samuel T. Harris @ 1998-04-28  0:00 UTC (permalink / raw)



Patrick D. Rogers wrote:
> 
> Samuel T. Harris wrote:
> >
> > Robert A Duff wrote:
> > >
> > > In article <rz84szje1ol.fsf@cs.williams.edu>,
> > > Jay Sachs  <sachs@cs.williams.edu> wrote:
> > > >       type Stack(Size : Integer := 100) is private;
> > >
> > > >...  What is the reason that the default initialization
> > > >seems to be ignored in the discriminant for the private type?
> > >
> > > The default isn't being ignored; Size is being correctly initialized to
> > > 100.  However, the mere presence of a default means that the
> > > discriminant can change.  That's confusing, and is a language design
> > > flaw, IMHO.  There should have been a separate keyword or some other
> > > separate syntax to mean "the discrim might change".  But as it is in
> > > Ada, an unconstrained variable of type Stack can later have a discrim of
> > > Integer'Last, even though it defaults initially to 100.  And many
> > > compilers take the (quite reasonable) attitude that implicit heap
> > > allocation is evil, so they allocate the maximum possible size for these
> > > things.  And in this case, that's enormous, and will typically raise
> > > Storage_Error; hence the warning.
> >
> > Not entirely accurate. The mere presense of the default value does
> > not mean the discriminant can change. It depends on how objects
> > are declared.
> 
> Sam,
> 
> Since we are in pedantic mode, :) Bob said "... unconstrained variable
> ...", so he is indeed entirely accurate.
> 
> :)
> 
> --pat
> 
> Patrick Rogers

To one-up the pedantic theme :) Bob's "... unconstrained variable"
appears several lines after "a default means that the discriminant
can change". Perhaps I should have said "Not entirely complete."

Bob covers unconstrained variables exclusively.
I simply sought to cover constrained variables and complete the picture.

The subtle differences are lost on many of our (my company's)
Ada initiates and I have spent some time explaining the nuances
of this construction, especially as applied to polymorphic variant
records.

Now, how's that for a recovery ;)

-- 
Samuel T. Harris, Principal Engineer
Raytheon Training Incorporated
"If you can make it, We can fake it!"




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
  1998-04-24  0:00 ` Jay Sachs
  1998-04-24  0:00   ` Joel VanLaven
       [not found]   ` <Es3A4J.Ion@world.std.com>
@ 1998-04-30  0:00   ` Anonymous
       [not found]     ` <6ib6t4$63f$1@goanna.cs.rmit.edu.au>
  2 siblings, 1 reply; 9+ messages in thread
From: Anonymous @ 1998-04-30  0:00 UTC (permalink / raw)



<35460201.ED1315C4@hso.link.com> <354612AF.41C6@hso.link.com>
<35468F93.C371940@hso.link.com>

On Wed, 29 Apr 1998 22:30:08 GMT, robertduff@world.std.com (Robert A
Duff) wrote:

> ...
> For such variables a compiler will either allocate the max size, or use
> the heap implicitly to grow and shrink the thing behind the scenes.  I
> prefer the former implementation in a fairly low-level, machine-oriented
> language like Ada.  On the other hand, the deallocate/reallocate scheme
> gives useful flexibility.  On the third hand, the first compiler I used

--                                  third hand!

> that tried that scheme had a bug -- if you renamed a component of such a
> record, the compiler would store the address of the renamed component,
> but then when the discriminant changed, the whole record would move, and
> the renaming would be a dangling pointer.  I believe at least one other
> compiler did it right, by doing the dealloc/realloc thing on just the
> parts that change size depending on the discrim (and you're not allowed
> to rename those components).
> 
> ...

Now we know the truth: Robert A. Duff is a Motie!

Jeff Carter  PGP:1024/440FBE21
My real e-mail address: ( carter @ innocon . com )
"You empty-headed animal-food-trough wiper."
Monty Python & the Holy Grail

Posted with Spam Hater - see
http://www.compulink.co.uk/~net-services/spam/




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
       [not found] <matthew_heaney-ya023680003004981720560001@news.ni.net>
@ 1998-05-01  0:00 ` Anonymous
  0 siblings, 0 replies; 9+ messages in thread
From: Anonymous @ 1998-05-01  0:00 UTC (permalink / raw)



<Es7569.4n2@world.std.com> <rz84szje1ol.fsf@cs.williams.edu>
<199804301352.PAA20159@basement.replay.com> <Es8xLp.MG0@world.std.com>

On Thu, 30 Apr 1998 17:20:56 -0800, matthew_heaney@acm.org (Matthew
Heaney) wrote:

> In article <Es8xLp.MG0@world.std.com>, robertduff@world.std.com (Robert A
> Duff) wrote:
> 
> (start of quote)
> On the other hand, my hand was griping more than gripping.  ;-)  If
> anybody complains that Ada is too complicated, show them English.
> (end of quote)
> 
> Funny, in his critique of the Green language, Dijkstra remarked that "the
> small list of 72 [reserved] words" is a "vocabulary of more than 10 percent
> of Basic English!"
> 
> My question to Edsger is, 10 percent of Basic English, compared to what?
> 
> 

I'm not Edsger Dijkstra, but I'll take a shot.

Basic English is an attempt to create an easy-to-learn common language.
It is English with a simplified syntax and a small vocabulary that could
be used for most everyday interactions. All verbs are regular, all
plurals are formed the same way, and so on. For example, one would say
"I goed" rather than "I went".

Information extracted from my brain. It got there from reading Websters
Collegiate Dictionary (1954), which I don't have available as I write
this. This process may introduce errors. However, a quick web search
finds

http://eldred.ne.mediaone.net/cko/begr.html

Jeff Carter  PGP:1024/440FBE21
My real e-mail address: ( carter @ innocon . com )
"You empty-headed animal-food-trough wiper."
Monty Python & the Holy Grail

Posted with Spam Hater - see
http://www.compulink.co.uk/~net-services/spam/




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
       [not found] <Es7569.4n2@world.std.com>
  1998-04-24  0:00 ` Jay Sachs
@ 1998-05-01  0:00 ` Samuel T. Harris
  1 sibling, 0 replies; 9+ messages in thread
From: Samuel T. Harris @ 1998-05-01  0:00 UTC (permalink / raw)



Robert A Duff wrote:
> 
> In article <35468F93.C371940@hso.link.com>,
> Samuel T. Harris <sam_harris@hso.link.com> wrote:
> >To one-up the pedantic theme :) Bob's "... unconstrained variable"
> >appears several lines after "a default means that the discriminant
> >can change". Perhaps I should have said "Not entirely complete."
> 
> :-)
> 
> Actually, what I *should* have said was, "The mere presence of a
> defaulted discrim (in the type decl) means that it is possible to create
> unconstrained variables of the type; the discriminants of such variables
> can change (but only by whole-record assignment)."

<-snip lots of good stuff ->

> >The subtle differences are lost on many of our (my company's)
> >Ada initiates and I have spent some time explaining the nuances
> >of this construction, especially as applied to polymorphic variant
> >records.
> 
> I would blame that on non-intuitive language rules.  Not on the poor
> programmers, who reasonably, but incorrectly, think that default
> expressions are for giving default values to discriminants.

Just so. These initiates are simply new to Ada, not poor programmers.

> 
> - Bob
> 

-- 
Samuel T. Harris, Principal Engineer
Raytheon Training Incorporated
"If you can make it, We can fake it!"




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: private type discriminants ignored?
       [not found]     ` <6ib6t4$63f$1@goanna.cs.rmit.edu.au>
@ 1998-05-06  0:00       ` Robert I. Eachus
  0 siblings, 0 replies; 9+ messages in thread
From: Robert I. Eachus @ 1998-05-06  0:00 UTC (permalink / raw)



In article <6ib6t4$63f$1@goanna.cs.rmit.edu.au> Dale Stanbrough <dale@goanna.cs.rmit.edu.au> writes:

  > It seems from the preceeding set of rules about discriminants that 
  > they too are a complicated morrass. Are discriminants really that 
  > useful to be worth the effort? I look at all the rules (in the LRM)
  > for them, and the code in Gnat, and it seems there is a lot of work
  > trying to get them right. Perhaps I don't write the sort of code
  > that they were intended to make simple, but I've rarely found them
  > that useful.

   There are several different cases that individually very useful.
For example, record types containing arrays whose bounds depend on a
discriminant with defaults.  (Whew!)  We really need a name for those.
They allow you to create types which correspond to char(N) varying in
PL/I:

    subtype Index is Integer range 0..100;

    type VString(Size: Index := 0) is record
      Value: String(1..Size);
    end record;

    Objects of type VString can contain strings of different sizes:

    V: VString;
    ...
    V := (6,"String");
    V := (27, "This is a test of VStrings.")

    Of course, instead of counting and using aggregates, you provide
operations for the type that do all that for you:

    V := + "This is a much longer string to assign to V.";

    By the way, in Ada 95, there is a package for varying strings.
But 1) the above allows the package body to be written in Ada. and
    2) you occaisionally need this feature for types other than
strings.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~1998-05-06  0:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <matthew_heaney-ya023680003004981720560001@news.ni.net>
1998-05-01  0:00 ` private type discriminants ignored? Anonymous
     [not found] <Es7569.4n2@world.std.com>
1998-04-24  0:00 ` Jay Sachs
1998-04-24  0:00   ` Joel VanLaven
     [not found]   ` <Es3A4J.Ion@world.std.com>
1998-04-28  0:00     ` Samuel T. Harris
1998-04-28  0:00       ` Patrick D. Rogers
1998-04-28  0:00         ` Samuel T. Harris
1998-04-30  0:00   ` Anonymous
     [not found]     ` <6ib6t4$63f$1@goanna.cs.rmit.edu.au>
1998-05-06  0:00       ` Robert I. Eachus
1998-05-01  0:00 ` Samuel T. Harris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox