Version 1.12 of ai05s/ai05-0228-1.txt

Unformatted version of ai05s/ai05-0228-1.txt version 1.12
Other versions for file ai05s/ai05-0228-1.txt

!standard 3.3.1(11)          11-05-05 AI05-0228-1/05
!standard 3.3.1(13)
!standard 3.3.1(21)
!standard 3.5(56/2)
!standard 3.6(22/2)
!standard 6.4.1(13)
!standard 13.13.2(35/2)
!class Amendment 10-10-22
!status Amendment 2012 11-03-11
!status ARG Approved 7-0-0 11-02-19
!status work item 10-10-22
!status received 10-10-22
!priority Medium
!difficulty Easy
!subject Default initial values for scalar and array types
!summary
Two new aspects are added to provide default initial values for scalar types and arrays of scalar types.
!problem
The new predicate (see AI05-0153-3) and invariant (see AI05-0146-1) aspects provide unreliable results for objects that are not initialized. This can be prevented when a default initial value is provided.
It is easy to provide a default initial value for record types, and access types have one defined by the language, but for other kinds of types, it is impossible.
This seems bizarre, given that implementations have the capability of doing default initialization (as for record and access types).
!proposal
Add an aspect Default_Value that can be used on all scalar types, and an additional aspect Default_Component_Value that can be used on all array of scalar types.
!wording
Add a new bullet after 3.3.1(11):
* The implicit initial value for a scalar subtype that has the Default_Value
aspect specified is the value of that aspect converted to the nominal subtype (which might raise Constraint_Error - see 4.6, “Type Conversions”);
AARM Ramification: This is a dynamic semantics rule, so the visibility of the aspect specification is not relevant -- if the full type for a private type has the Default_Value aspect specified, partial views of the type also have this implicit initial value.
Modify 3.3.1(13):
* For a (definite) composite subtype, the implicit initial value of each
component with a default_expression is obtained by evaluation of this expression and conversion to the component's nominal subtype (which might raise Constraint_Error [- see 4.6, "Type Conversions"]), unless the component is a discriminant of a constrained subtype (the previous case), or is in an excluded variant (see 3.8.1). For each component that does not have a default_expression, {if the composite subtype has the Default_Component_Value aspect specified, the implicit initial value is the value of that aspect converted to the component's nominal subtype; otherwise, } any implicit initial values are those determined by the component's nominal subtype.
[Editor's note: We delete the cross-reference because it has been moved into the new bullet; we don't repeat cross-references in paragraphs that will be read together.]
Modify 3.3.1(21):
There is no implicit initial value defined for a scalar subtype{ unless the Default_Value aspect has been specified for the type}. In the absence of an explicit initialization{ or the specification of the Default_Value aspect}, a newly created scalar object might have a value that does not belong to its subtype (see 13.9.1 and H.1).
Add after 3.5(56/2):
Static Semantics
For a scalar type, the following language-defined representation aspect may be specified with an aspect_specification:
Default_Value
This aspect shall be specified by a static expression, and that expression shall be explicit, even if the aspect has a boolean type. Default_Value shall be specified only on a full_type_declaration.
AARM Reason: The part about requiring an explicit expression is to disallow omitting the value for this aspect, which would otherwise be allowed by the rules of 13.3.1.
This is a representation aspect in order to disallow specifying it on a derived type that has inherited primitive subprograms; that is necessary as the sizes of out parameters could be different whether or not a Default_Value is specified (see 6.4.1). End AARM Reason.
If a derived type with no primitive subprograms inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
AARM Reason: This is to override the 13.3.1 rule that says that a boolean aspect with a value True cannot be changed.
Name Resolution
The expected type for the expression specified for the Default_Value aspect is the type defined by the full_type_declaration on which it appears.
Add after 3.6(22/2):
Static Semantics
For an array type with a scalar component type, the following language-defined representation aspect may be specified with an aspect_specification:
Default_Component_Value
This aspect shall be specified by a static expression, and that expression shall be explicit, even if the aspect has a boolean type. Default_Component_Value shall be specified only on a full_type_declaration.
AARM Reason: The part about requiring an explicit expression is to disallow omitting the value for this aspect, which would otherwise be allowed by the rules of 13.3.1.
If a derived type with no primitive subprograms inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
AARM Reason: This is to override the 13.3.1 rule that says that a boolean aspect with a value True cannot be changed for a derived type.
Name Resolution
The expected type for the expression specified for the Default_Component_Value aspect is the component type of the array type defined by the full_type_declaration on which it appears.
Add a new bullet after 6.4.1(13): [Note that 6.4.1(13) was modified by AI05-0196-1 -- we echo that wording here, not the original wording.]
* For a scalar type that has the Default_Value aspect specified, the formal parameter
is initialized from the value of the actual, without checking that the value satisfies any constraint;
AARM Reason: This preserves the language design principle that all objects of a type with an implicit initial value are initialized. This is important so that a programmer can guarantee that all objects of a scalar type have a valid value with a carefully chosen Default_Value.
AARM Implementation Note: This rule means that out parameters of a subtype T with a specified Default_Value need to be large enough to support any possible value of the base type of T. In contrast, a type that does not have a Default_Value only need support the size of the subtype (since no values are passed in).
[Editor's note: We don't need to modify the composite rule, as the changed definition of "implicit initial values" effectively changes this rule to include arrays with a specified Default_Component_Value.]
Modify AARM 6.4.1(15.a):
This case covers scalar types {that do not have Default_Value specified}, and composite types whose subcomponent's subtypes do not have any implicit initial values. The view conversion for composite types ensures that if the lengths don't match between an actual and a formal array parameter, the Constraint_Error is raised before the call, rather than after.
Modify 13.13.2(35/2):
In the default implementation of Read and Input for a composite type, for each scalar component that is a discriminant or [whose component_declaration includes a default_expression]{that has an implicit initial value}, a check is made that the value returned by Read for the component belongs to its subtype. Constraint_Error is raised if this check fails. For other scalar components, no check is made. For each component that is of an access type, if the implementation can detect that the value returned by Read for the component is not a value of its subtype, Constraint_Error is raised. If the value is not a value of its subtype and this error is not detected, the component has an abnormal value, and erroneous execution can result (see 13.9.1). In the default implementation of Read for a composite type with defaulted discriminants, if the actual parameter of Read is constrained, a check is made that the discriminants read from the stream are equal to those of the actual parameter. Constraint_Error is raised if this check fails.
AARM To Be Honest: An implementation should always be able to detect the error for a null value read into an access subtype with a null exclusion; the "if the implementation can detect" is intended to cover non-null access values.
AARM Ramification: A scalar component can have an implicit initial value if it has a default_expression, if the component's type has the Default_Value aspect specified, or if the component is that of an array type that has the Default_Component_Value aspect specified.
!discussion
It is important that the default initial value be something that makes sense for the type. Simply initializing everything to zero is just as likely to cover bugs as eliminate them.
However, if a type has a value specifically that means "Unknown" or "Undefined", it makes perfect sense to initialize all objects to that value. That would greatly reduce the chances of invalid objects of the type existing.
We considered making these subtype aspects rather than type aspects. That would allow giving different default values to different subtypes. However, given the existence of many ways to create anonymous subtypes it would be very hard to guarantee that all values of a type are initialized. Without that guarantee, these aspects lose a lot of their purpose.
!examples
Providing a default initial value for an enumeration type with an unknown value:
type Item_State is (Unknown, Fooey, Blarch, ...) with Default_Value => Unknown;
Providing string type that is initialized with blanks:
type Blank_String is array (Positive range <>) of Character with Default_Component_Value => ' ';
!corrigendum 3.3.1(11)
Insert after the paragraph:
the new paragraph:
!corrigendum 3.3.1(13)
Replace the paragraph:
For a (definite) composite subtype, the implicit initial value of each component with a default_expression is obtained by evaluation of this expression and conversion to the component's nominal subtype (which might raise Constraint_Error — see 4.6, "Type Conversions"), unless the component is a discriminant of a constrained subtype (the previous case), or is in an excluded variant (see 3.8.1). For each component that does not have a default_expression, any implicit initial values are those determined by the component's nominal subtype.
by:
For a (definite) composite subtype, the implicit initial value of each component with a default_expression is obtained by evaluation of this expression and conversion to the component's nominal subtype (which might raise Constraint_Error), unless the component is a discriminant of a constrained subtype (the previous case), or is in an excluded variant (see 3.8.1). For each component that does not have a default_expression, if the composite subtype has the Default_Component_Value aspect specified, the implicit initial value is the value of that aspect converted to the component's nominal subtype; otherwise, any implicit initial values are those determined by the component's nominal subtype.
!corrigendum 3.3.1(21)
Replace the paragraph:
There is no implicit initial value defined for a scalar subtype. In the absence of an explicit initialization, a newly created scalar object might have a value that does not belong to its subtype (see 13.9.1 and H.1).
by:
There is no implicit initial value defined for a scalar subtype unless the Default_Value aspect has been specified for the type. In the absence of an explicit initialization or the specification of the Default_Value aspect, a newly created scalar object might have a value that does not belong to its subtype (see 13.9.1 and H.1).
!corrigendum 3.5(56/2)
Insert after the paragraph:
An implementation may extend the Wide_Wide_Value, Wide_Value, Value, Wide_Wide_Image, Wide_Image, and Image attributes of a floating point type to support special values such as infinities and NaNs.
the new paragraphs:
Static Semantics
For a scalar type, the following language-defined representation aspect may be specified with an aspect_specification (see 13.1.1):
Default_Value
This aspect shall be specified by a static expression, and that expression shall be explicit, even if the aspect has a boolean type. Default_Value shall be specified only on a full_type_declaration.
If a derived type with no primitive subprograms inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type.
Name Resolution Rules
The expected type for the expression specified for the Default_Value aspect is the type defined by the full_type_declaration on which it appears.
!corrigendum 3.6(22)
Insert after the paragraph:
The elaboration of a discrete_subtype_definition that does not contain any per-object expressions creates the discrete subtype, and consists of the elaboration of the subtype_indication or the evaluation of the range. The elaboration of a discrete_subtype_definition that contains one or more per-object expressions is defined in 3.8. The elaboration of a component_definition in an array_type_definition consists of the elaboration of the subtype_indication or access_definition. The elaboration of any discrete_subtype_definitions and the elaboration of the component_definition are performed in an arbitrary order.
the new paragraphs:
Static Semantics
For an array type with a scalar component type, the following language-defined representation aspect may be specified with an aspect_specification (see 13.1.1):
Default_Component_Value
This aspect shall be specified by a static expression, and that expression shall be explicit, even if the aspect has a boolean type. Default_Component_Value shall be specified only on a full_type_declaration.
If a derived type with no primitive subprograms inherits a boolean Default_Component_Value aspect, the aspect may be specified to have any value for the derived type.
Name Resolution Rules
The expected type for the expression specified for the Default_Component_Value aspect is the component type of the array type defined by the full_type_declaration on which it appears.
!corrigendum 6.4.1(13)
Insert after the paragraph:
For an access type, the formal parameter is initialized from the value of the actual, without a constraint check;
the new paragraph:
For a scalar type that has the Default_Value aspect specified, the formal parameter is initialized from the value of the actual, without checking that the value satisfies any constraint;
!corrigendum 13.13.2(35)
Replace the paragraph:
In the default implementation of Read and Input for a composite type, for each scalar component that is a discriminant or whose component_declaration includes a default_expression, a check is made that the value returned by Read for the component belongs to its subtype. Constraint_Error is raised if this check fails. For other scalar components, no check is made. For each component that is of an access type, if the implementation can detect that the value returned by Read for the component is not a value of its subtype, Constraint_Error is raised. If the value is not a value of its subtype and this error is not detected, the component has an abnormal value, and erroneous execution can result (see 13.9.1). In the default implementation of Read for a composite type with defaulted discriminants, if the actual parameter of Read is constrained, a check is made that the discriminants read from the stream are equal to those of the actual parameter. Constraint_Error is raised if this check fails.
by:
In the default implementation of Read and Input for a composite type, for each scalar component that is a discriminant or that has an implicit initial value, a check is made that the value returned by Read for the component belongs to its subtype. Constraint_Error is raised if this check fails. For other scalar components, no check is made. For each component that is of an access type, if the implementation can detect that the value returned by Read for the component is not a value of its subtype, Constraint_Error is raised. If the value is not a value of its subtype and this error is not detected, the component has an abnormal value, and erroneous execution can result (see 13.9.1). In the default implementation of Read for a composite type with defaulted discriminants, if the actual parameter of Read is constrained, a check is made that the discriminants read from the stream are equal to those of the actual parameter. Constraint_Error is raised if this check fails.
!ACATS test
ACATS tests would be needed for this aspect.
!appendix

[Editor's note: This thread forked off of a discussion of predicates.]

From: Robert Dewar
Sent: Wednesday, October 13, 2010  11:21 AM

> Well, yeah.  We get a lot of support calls about uninit vars.
> Too bad there's no language feature to prevent those bugs.

All language features that "fix" uninitialized variables are evil. Requiring
default initialization or providing default implicit initialization are
particularly evil in my view.

****************************************************************

From: Bob Duff
Sent: Wednesday, October 13, 2010  12:33 PM

> All language features that "fix" uninitialized variables are evil.

I won't touch that with a barge pole.  ;-)

Anyway, it's irrelevant to my point, which is that uninit vars are a loophole in
constraints, so the argument "predicates must be loophole-free, because
constraints are" is bogus.

>... Requiring default initialization or providing default implicit
>initialization are particularly evil in my view.

I certainly agree with that.

Too bad JDI didn't (I'm talking about access types).

****************************************************************

From: Tucker Taft
Sent: Wednesday, October 13, 2010  1:01 PM

>> ... Requiring default initialization or providing default implicit
>> initialization are particularly evil in my view.
>
> I certainly agree with that.
>
> Too bad JDI didn't (I'm talking about access types).

The default initial value of "null" for an access type seems OK, since you get
an exception if you try to use it as though it had a usable non-null value.

It is a default initial value of zero that is dangerous, since it is not
distinguishable from a "true" initial value of zero.  If there were a "null"
value for all types, which corresponded roughly to a floating point signaling
NaN, that would be fine in my view.  You would get notified if you tried to do
anything that presumed the object had an "intentional" initial value.

****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 13, 2010  1:50 PM

Right. The annoying thing is that Ada doesn't have a way to set a default
initial value for scalar and array types, for those cases where there is an
"obviously" bad value. For instance, many of my enumeration types have an value
of "unknown" or something like that. It's purpose is exactly to provide a value
for those cases where something has gone wrong or nothing has been calculated
yet. Typically, it would be used (manually of course) as a default initial value
for objects; it would be nice to be able to force all objects to start with that
value rather than random garbage. Ada compilers clearly have the mechanism to
deal with default initializations (because of access types and record
components), so it is annoying that the programmer can't use that when it is
appropriate.

****************************************************************

From: Robert Dewar
Sent: Wednesday, October 13, 2010  5:29 PM

TW, on the IM 7040, there was a great instruction intended only for system
diagnostics to set parity wrong on a specified word.

WATFor fortran used this to initialize all uninitialized variables (under some
option flag). And you got a parity error if you tried to load the value.

BTW, I don't think it is worth spending too much time on different checking
modes. Compilers will likely provide different checking modes anyway, whatever
the standard says.

****************************************************************

From: Robert Dewar
Sent: Wednesday, October 13, 2010  5:27 PM

>> It is a default initial value of zero that is dangerous, since it is
>> not distinguishable from a "true" initial value of zero.  If there
>> were a "null" value for all types, which corresponded roughly to a
>> floating point signaling NaN, that would be fine in my view.  You
>> would get notified if you tried to do anything that presumed the
>> object had an "intentional" initial value.

Big overhead in the array case having to check, and the trouble is that you MUST
be able to have 32 tc integers, represented in the obvious way. It would be a
menace if Ada insisted on stealing one value.

> Ada
> compilers clearly have the mechanism to deal with default
> initializations (because of access types and record components), so it
> is annoying that the programmer can't use that when it is appropriate.

Good point, I think I will invent a pragma. In fact the obvious pragma to extend
is

pragma Initialize_Scalars;

and allow the usage

pragma Initialize_Scalars (local_type_NAME);

20 minutes work to allow this!

****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 13, 2010  5:44 PM

> >> It is a default initial value of zero that is dangerous, since it
> >> is not distinguishable from a "true" initial value of zero.  If
> >> there were a "null" value for all types, which corresponded roughly
> >> to a floating point signaling NaN, that would be fine in my view.
> >> You would get notified if you tried to do anything that presumed
> >> the object had an "intentional" initial value.
>
> Big overhead in the array case having to check, and the trouble is
> that you MUST be able to have 32 tc integers, represented in the
> obvious way. It would be a menace if Ada insisted on stealing one
> value.

I agree that it doesn't make sense to do it in all cases; it's just odd to not
have the capability when it is useful. [That's Tucker's quote, BTW.]

> > Ada
> > compilers clearly have the mechanism to deal with default
> > initializations (because of access types and record components), so
> > it is annoying that the programmer can't use that when it is appropriate.
>
> Good point, I think I will invent a pragma. In fact the obvious pragma
> to extend is
>
> pragma Initialize_Scalars;
>
> and allow the usage
>
> pragma Initialize_Scalars (local_type_NAME);
>
> 20 minutes work to allow this!

At one point, someone suggested having an aspect for this purpose. That would
look something like:

    type Item_State is (Unknown, Fooey, Blarch, ...)
       with Default_Initial_Value => Unknown;

This seems like a good use for an aspect, given that it isn't something that
ought to be dependent on the view of the type (or subtype, if we wanted to allow
that).

The (minor) advantage of the aspect over the pragma is that it allows the
default value to be specified; that might be helpful if the "Unknown" value is
not the first one in the enumeration.

****************************************************************

From: Robert Dewar
Sent: Wednesday, October 13, 2010  6:00 PM

Well we could allow a default value for Initialize_Scalars or some other pragma.
IS in GNAT is not always the lowest value, and can in fact be changed at link
time or even execution time (the idea is to try different initial values and see
if has an observable effect

A disadvantage of an aspect if that is the only mechanism is that it is
restricted to Ada 2012 mode. We have a lot of customers still stuck at Ada 95
(partly because of the high level of incompatibility between Ada 95 and Ada
2005).

****************************************************************

From: Tucker Taft
Sent: Wednesday, October 13, 2010  6:10 PM

I believe we already discussed something along these lines in the recent ARG
meeting.  Didn't we invent an aspect spec like "with Default => blah"? Or am I
dreaming that?

****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 13, 2010  6:37 PM

I think we invented it, but I don't think anyone took ownership of it and got it
added to the agenda. As such, it is now too late (it wasn't included in the
scope approved by WG 9), unless someone can figure out a reason why we need to
add it for one of the existing AIs.

****************************************************************

From: Robert Dewar
Sent: Wednesday, October 13, 2010  6:47 PM

Sounds good to me, I think I will implement the aspect and the corresponding
pragma, so it really doesn't matter too much if it gets into the standard. It's
a good idea!

****************************************************************

From: Jean-Pierre Rosen
Sent: Thursday, October 14, 2010  3:48 AM

I was about to suggest an aspect too, but Randy shot first...

> A disadvantage of an aspect if that is the only mechanism is that it
> is restricted to Ada 2012 mode. We have a lot of customers still stuck
> at Ada 95 (partly because of the high level of incompatibility between
> Ada 95 and Ada 2005).

OTOH, people will move to the new versions if the benefits balance the
disagreements. Providing nice features in the most recent modes is a way to push
them.

****************************************************************

From: Robert Dewar
Sent: Thursday, October 14, 2010  6:13 PM

Well in fact in GNAT we systematically provide pragmas to match all aspects in
any case, the way the internal implementation of aspects work is to translate to
the corresponding pragma or attribute definition clause. So for example, we now
have pragma predicate and pragma invariant in GNAT.

We are more in the business of providing useful features to people than pushing
them to use the latest version of Ada. As I say, the biggest barrier is the
rather fierce upwards incompatibility of Ada 2005, this has resulted in a
barrier for several large users (the issue with return of limited stuff).

We have talked about a mode which would provide Ada 95 + all compatible
features, but this is quite a bit of work.

****************************************************************

From: Robert Dewar
Sent: Monday, November 22, 2010  6:17 PM

I am not sure I understand the restriction to full type declarations, it seems
quite reasonable (and of course trivially implementable) to have a different
default value for a derived type, and that may be quite reasonable when the
derived type has a range.

Oh well, don't really mind much,

but in either case, the question arises of whether subtypes inherit these
aspects (yes of course, though this may result in invalid values).

Do derived types inherit these aspects (I would think yes, especially if you
can't specify it on the derived type).

****************************************************************

From: Steve Baird
Sent: Monday, November 22, 2010  6:27 PM

> I am not sure I understand the restriction to full type declarations,
> it seems quite reasonable (and of course trivially implementable) to
> have a different default value for a derived type, and that may be
> quite reasonable when the derived type has a range.


A full_type_declaration does not exclude a derived type.

I think the AI permits specifying the Default_Initial_Value aspect of a derived
scalar type.

****************************************************************

From: Randy Brukardt
Sent: Monday, November 22, 2010  6:38 PM

> I am not sure I understand the restriction to full type declarations,
> it seems quite reasonable (and of course trivially implementable) to
> have a different default value for a derived type, and that may be
> quite reasonable when the derived type has a range.

I don't understand this comment. A derived type is a full type declaration
(specifically, a derived_type_definition is a kind of type_definition, and
3.2.1(3) says that a full type declaration includes all kinds of type
definitions.

Here we simply mean that you can't specify this on partial or incomplete views
(which are not full type declarations).

> Oh well, don't really mind much,
>
> but in either case, the question arises of whether subtypes inherit
> these aspects (yes of course, though this may result in invalid
> values).

Yes, of course. Even the type can have an invalid value:

    type Small_Int is range 0 .. 99 with Default_Value => -1;

> Do derived types inherit these aspects (I would think yes, especially
> if you can't specify it on the derived type).

We answer that with the standard rules for inheritance of aspects. However, we
need to decide if this is representational or operational to answer that, and
then if the latter we still need to define it. So I think this is a valid
question, but the answer should clearly be yes. (Why not??)

****************************************************************

From: Robert Dewar
Sent: Monday, November 22, 2010  7:04 PM

> A full_type_declaration does not exclude a derived type.

Yes of course, my mistake

> I think the AI permits specifying the
> Default_Initial_Value aspect of a derived scalar type.

So the restriction is the usual one, that we can only specify this for a first
subtype, which is fine.

****************************************************************

From: Tucker Taft
Sent: Monday, November 22, 2010  7:32 PM

> I am not sure I understand the restriction to full type declarations,
> it seems quite reasonable (and of course trivially implementable) to
> have a different default value for a derived type, and that may be
> quite reasonable when the derived type has a range.

I believe we intended to allow this on a derived type.  A derived type
declaration is still a "full" type declaration.

> Oh well, don't really mind much,
>
> but in either case, the question arises of whether subtypes inherit
> these aspects (yes of course, though this may result in invalid
> values).

I don't follow here.  If the value is outside the subtype, then that is like a
null-excluding access type. You have to explicitly initialize it or you get a
constraint_error.  I don't see how you end up with an invalid value.

>
> Do derived types inherit these aspects (I would think yes, especially
> if you can't specify it on the derived type).

I would certainly expect derived types to inherit the "Default_Value" aspect.

****************************************************************

From: Robert Dewar
Sent: Monday, November 22, 2010  7:37 PM

> I believe we intended to allow this on a derived type.  A derived type
> declaration is still a "full" type declaration.

Indeed, this is just my silly mistake

>>
>> Oh well, don't really mind much,
>>
>> but in either case, the question arises of whether subtypes inherit
>> these aspects (yes of course, though this may result in invalid
>> values).
>
> I don't follow here.  If the value is outside the subtype, then that
> is like a null-excluding access type.
> You have to explicitly initialize it or you get a constraint_error.  I
> don't see how you end up with an invalid value.

This is weird, so if we have

    type R is range 1 .. 10 with
       Default_Value => 1;

    subtype S is R range 2 .. 10;

then

    X : S;

will generate a constraint_Error, seems a bit awkward, but OK.

****************************************************************

From: Bob Duff
Sent: Monday, November 22, 2010  7:43 PM

> Yes, of course. Even the type can have an invalid value:
>
>     type Small_Int is range 0 .. 99 with Default_Value => -1;

...which might even be useful (can't declare objects), although I suppose:

    type T(<>) is private;

is still preferable.

> We answer that with the standard rules for inheritance of aspects.
> However, we need to decide if this is representational or operational
> to answer that, and then if the latter we still need to define it. So
> I think this is a valid question, but the answer should clearly be
> yes. (Why not??)

I agree (derived types should inherit).

****************************************************************

From: Robert Dewar
Sent: Monday, November 22, 2010  8:07 PM

One other question, do we really want to delay these expressions. In general it
seems peculiar to delay static expression evaluation, e.g.

     Standard_Default : constant := 0;

     ....

     type R is range 0 .. 10 with
       Default_Value => Standard_Default;

     ..

     Standard_Default_Value constant := 1;

     RR : R;

Do we really want to go to the trouble of insisting that the default value be 1
in this case, seems odd, and for sure makes the handling of the check for
consistent visibility more tricky, since you don't know without fiddling at the
freeze point what the resolving type will be.

Well just raising the question, it's manageable either way with some fiddling!

****************************************************************

From: Randy Brukardt
Sent: Monday, November 22, 2010  8:29 PM

> One other question, do we really want to delay these expressions.

I think we have to, as otherwise the default value expression would have to freeze the type instantly. That doesn't seem desirable.

> In general it seems peculiar to delay static expression evaluation,
> e.g.
>
>      Standard_Default : constant := 0;
>
>      ....
>
>      type R is range 0 .. 10 with
>        Default_Value => Standard_Default;
>
>      ..
>
>      Standard_Default_Value constant := 1;
>
>      RR : R;
>
> Do we really want to go to the trouble of insisting that the default
> value be 1 in this case, seems odd, and for sure makes the handling of
> the check for consistent visibility more tricky, since you don't know
> without fiddling at the freeze point what the resolving type will be.

This is true, but immediate resolution/evaluation also means that you can't have
a typed constant as the default value:

    type RLB is range 0 .. 10 with Default_Value => Unknown;
    Unknown : constant RLB := 0;

This latter usage seems like the way I would write this, and I was rather
expecting that it would work.

****************************************************************

From: Robert Dewar
Sent: Monday, November 22, 2010  8:49 PM

>> One other question, do we really want to delay these expressions.
>
> I think we have to, as otherwise the default value expression would
> have to freeze the type instantly. That doesn't seem desirable.

You are right!

> This is true, but immediate resolution/evaluation also means that you
> can't have a typed constant as the default value:
>
>      type RLB is range 0 .. 10 with Default_Value =>  Unknown;
>      Unknown : constant RLB := 0;
>
> This latter usage seems like the way I would write this, and I was
> rather expecting that it would work.

Agreed, it should work!

****************************************************************

From: Bob Duff
Sent: Monday, November 22, 2010  7:49 PM

> This is weird, so if we have
>
>     type R is range 1 .. 10 with
>        Default_Value => 1;
>
>     subtype S is R range 2 .. 10;
>
> then
>
>     X : S;
>
> will generate a constraint_Error, seems a bit awkward, but OK.

Yes, weird/awkward, but OK.

The "not null" thing is broken, IMHO, because the null-default is forced upon
you.  But here, you asked for "2..10", and you also asked for default of "1", so
it makes perfect sense to ding you with C_E on "X : S;".  This case is not
broken, unlike the not-null access type case.

****************************************************************

From: Robert Dewar
Sent: Tuesday, November 23, 2010  4:18 PM

Seems a pity you cannot use Initial_Value to control the creation of
invalid values.

****************************************************************

From: Bob Duff
Sent: Tuesday, November 23, 2010  4:18 PM

I don't understand what you mean by "control the creation...".

If you say:

    package P is
        type T is private;
        ...
    private
        type T is range 200_000_000..400_000_000 with
            Default_Value => 0; -- default is invalid
    end P;

then any client of P that says "X: T;" will get a Constraint_Error.
If you leave off the "Default_Value", then no Constraint_Error.
Programmer of P has full control.

Is that not what you want?
Where's the "seems a pity" here?

****************************************************************

From: Robert Dewar
Sent: Tuesday, November 23, 2010  6:42 PM

I want to get a result similar to Normalize_Scalars, except selective, so
variables are initialized with an invalid value, which will cause a
constraint_Error when accessed (it's useless having the CE on creation for this
purpose!)

****************************************************************

From: Bob Duff
Sent: Tuesday, November 30, 2010  1:50 PM

This AI proposes attributes Default_Value and Default_Component_Value.
Several of us at AdaCore think that the "_Value" part is just noise, so we would
prefer Default and Component_Default.

What do other ARG members think?

P.S. If we must keep "_Value", I'd prefer Component_Default_Value over
Default_Component_Value.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, November 30, 2010  2:14 PM

I tried a number of names when I created this AI; I thought "Default" by itself
was too non-specific (there are a number of things that this could mean), thus I
settled on "Default_Value".

Note that any form of "Default" is really wrong, as the technical term in
question is "implicit initial value". But "Implicit_Initial_Value" seems way too
long. "Initial_Value" would be OK, but not clearly better than "Default_Value".
("Initial" by itself makes no sense.)

As far as "Default_Component_Value" goes, that is what Jean-Pierre suggested
during the meeting, no one suggested anything else, and honestly,
"Component_Default_Value" sounds wrong and contrived. I suspect that I'd usually
write "Default_Component_Value" and have to change it.

****************************************************************

From: Gary Dismukes
Sent: Tuesday, November 30, 2010  3:18 PM

> Note that any form of "Default" is really wrong, as the technical term
> in question is "implicit initial value". But "Implicit_Initial_Value"
> seems way too long. "Initial_Value" would be OK, but not clearly
> better than "Default_Value". ("Initial" by itself makes no sense.)

I could live with Initial_Value.  Actually I think I like it a bit better than
Default_Value, and as you say, it fits better terminology-wise.

> As far as "Default_Component_Value" goes, that is what Jean-Pierre
> suggested during the meeting, no one suggested anything else, and
> honestly, "Component_Default_Value" sounds wrong and contrived. I
> suspect that I'd usually write "Default_Component_Value" and have to change it.

Really?  I parse Component_Default_Value as "component's default value"
and Default_Component_Value as "default component's value".  The former seems
much better to me (it's what I mistakenly remembered as the chosen name in the
AI).  Obviously tastes vary.

****************************************************************

From: Bob Duff
Sent: Tuesday, November 30, 2010  4:37 PM

> I could live with Initial_Value.  Actually I think I like it a bit
> better than Default_Value, and as you say, it fits better terminology-wise.

I prefer Default_Value over Initial_Value, because it isn't really the initial
value in all cases -- it's the *default* initial value; i.e. the one used when
you don't specify an explicit one. Never mind the language-lawyerly terminology.

Besides, this feature is intended to mirror the fact that record components can
have defaults, and the syntax for those uses the term default_expression, so I
think Default_Value (or just Default) fits in OK.

Implicit_Initial_Value seems pretty awful to me.

> > As far as "Default_Component_Value" goes, that is what Jean-Pierre
> > suggested during the meeting,...

Jean-Pierre speaks French, and they put their adjectives and nouns in a
different order, so I'm not sure I trust his judgement here (despite his
excellent English -- far better than my French!).

>...no one suggested anything else, and honestly,
> > "Component_Default_Value" sounds wrong and contrived. I suspect that
> > I'd usually write "Default_Component_Value" and have to change it.
>
> Really?  I parse Component_Default_Value as "component's default value"
> and Default_Component_Value as "default component's value".  The
> former seems much better to me (it's what I mistakenly remembered as
> the chosen name in the AI).  Obviously tastes vary.

In this case, my taste matches Gary's.  It's the "default value"
for the component, not the "default" for the "component value", whatever that
might mean.

I also agree with Tucker's reasoning, but he hasn't weighed in on
Component_Default_Value (nor Component_Default).

****************************************************************

From: Gary Dismukes
Sent: Tuesday, November 30, 2010  4:59 PM

> I prefer Default_Value over Initial_Value, because it isn't really the
> initial value in all cases -- it's the *default* initial value; i.e.
> the one used when you don't specify an explicit one.
> Never mind the language-lawyerly terminology.
>
> Besides, this feature is intended to mirror the fact that record
> components can have defaults, and the syntax for those uses the term
> default_expression, so I think Default_Value (or just Default) fits in
> OK.

Good points.  The Default_* names seem preferable.

> Implicit_Initial_Value seems pretty awful to me.

Agreed (and I don't think anyone's arguing for that).

****************************************************************

From: Randy Brukardt
Sent: Tuesday, November 30, 2010  5:26 PM

...
> > I could live with Initial_Value.  Actually I think I like it a bit
> > better than Default_Value, and as you say, it fits better terminology-wise.
>
> I prefer Default_Value over Initial_Value, because it isn't really the
> initial value in all cases -- it's the *default* initial value; i.e.
> the one used when you don't specify an explicit one.
> Never mind the language-lawyerly terminology.

I'd argue that it is OK to think of it as the initial value in all cases, as
there is no side-effects to the evaluation of it and any explicit value would
overwrite it (allowing the compiler to eliminate the initial assignment). That
is, there is no difference between thinking of it as an always present initial
value and an implicit initial value used only when nothing else is specified.

> Besides, this feature is intended to mirror the fact that record
> components can have defaults, and the syntax for those uses the term
> default_expression, so I think Default_Value (or just Default) fits in
> OK.
>
> Implicit_Initial_Value seems pretty awful to me.

I do agree with that; it's just too long.

> > > As far as "Default_Component_Value" goes, that is what Jean-Pierre
> > > suggested during the meeting,...
>
> Jean-Pierre speaks French, and they put their adjectives and nouns in
> a different order, so I'm not sure I trust his judgement here (despite
> his excellent English -- far better than my French!).
>
> >...no one suggested anything else, and honestly,
> > > "Component_Default_Value" sounds wrong and contrived. I suspect
> > > that I'd usually write "Default_Component_Value" and have to change it.
> >
> > Really?

Yes.

>  I parse Component_Default_Value as "component's default value"
> > and Default_Component_Value as "default component's value".  The
> > former seems much better to me (it's what I mistakenly remembered as
> > the chosen name in the AI).  Obviously tastes vary.

But there is no possessive in these names, you're adding that for some
mysterious reason to me. I parse "Default_Component_Value" as "default
'component value'" which rearranged gives "default value of a component". I
can't parse "Component_Default_Value" at all; I would need to put the possessive
explicitly into the identifier in order to do that -- but that's impossible as '
can't be used in an identifier (I always rearrange identifiers when that
happens). Indeed, I'd be much more likely to use "Default_Value_of_Component"
than either of the proposed names if this was my code.

> In this case, my taste matches Gary's.  It's the "default value"
> for the component, not the "default" for the "component value",
> whatever that might mean.
>
> I also agree with Tucker's reasoning, but he hasn't weighed in on
> Component_Default_Value (nor Component_Default).

Tucker? He hasn't weighed in at all, at least on the ARG list where I can see
it. Did you mean someone else, or is this discussion going on somewhere else??

****************************************************************

From: Erhard Ploedereder
Sent: Tuesday, November 30, 2010  5:29 PM

I agree on "Default" over "Initial" (for the same reason as cited below.).

On the component values, ... etymologically interesting discussion :-)

Germans, being world champions in glueing words together to form new terms,
would never think of a syntax
   <noun> <adjective> <noun>
to do so. (Of course the correct syntax is <adjective>* <noun>+.)

For "Initial", this would have clearly argued for Initial_Component_Value.
For "Default", it's a wash.

****************************************************************

From: Robert Dewar
Sent: Tuesday, November 30, 2010  5:35 PM

Why don't we just leave it the way it is? There really seems no consensus for a
change :-)

****************************************************************

From: Bob Duff
Sent: Tuesday, November 30, 2010  7:09 PM

> I'd argue that it is OK to think of it as the initial value in all
> cases, as there is no side-effects to the evaluation of it and any
> explicit value would overwrite it (allowing the compiler to eliminate
> the initial assignment). That is, there is no difference between
> thinking of it as an always present initial value and an implicit
> initial value used only when nothing else is specified.

True.  But I don't like that way of thinking for the same reason I wouldn't
write "X: T := 0; X := 1; ...", where the "0" is not used.

> > I also agree with Tucker's reasoning, but he hasn't weighed in on
> > Component_Default_Value (nor Component_Default).
>
> Tucker? He hasn't weighed in at all, at least on the ARG list where I
> can see it. Did you mean someone else, or is this discussion going on
> somewhere else??

Sorry.  There was a private email discussion.  I then started this ARG
discussion, and then admonished everybody to reply to that, but they all replied
to the private discussion instead.  Sigh.

Anyway, Tuck's point was that Default_Component doesn't make sense.
He can repeat it here, if he likes, and possibly comment on whether he likes
Component_Default better.

****************************************************************

From: Robert Dewar
Sent: Tuesday, November 30, 2010  7:17 PM

>> I'd argue that it is OK to think of it as the initial value in all
>> cases, as there is no side-effects to the evaluation of it and any
>> explicit value would overwrite it (allowing the compiler to eliminate
>> the initial assignment). That is, there is no difference between
>> thinking of it as an always present initial value and an implicit
>> initial value used only when nothing else is specified.

Also you don't get a constraint_error if this initial value is out of range if
it is superceded by an explicit value, so that's another reason for not liking
this viewpoint (and name!)

****************************************************************

From: Tucker Taft
Sent: Tuesday, November 30, 2010  10:04 PM

>> I also agree with Tucker's reasoning, but he hasn't weighed in on
>> Component_Default_Value (nor Component_Default).
>
> Tucker? He hasn't weighed in at all, at least on the ARG list where I
> can see it. Did you mean someone else, or is this discussion going on
> somewhere else??

There were some messages passed around among a small group (mostly AdaCore),
before Bob posted the note to ARG.  I indicated I didn't like Default_Component.
Component_Default, Component_Default_Value, and Default_Component_Value are all
fine with me.

Default_Value is preferable to Default as far as I am concerned, though only
marginally.

Overall, sticking with "Default_Value" and "Default_Component_Value" seems
easiest at this point, because, as Robert pointed out, there is no consensus
about what to change to.

****************************************************************

From: Brad Moore
Sent: Wednesday, December  1, 2010  1:00 AM

For what its worth, my view is similar to Tuckers, but if I had to choose, I
like Default_Value and Default_Component_Value the best anyway.

****************************************************************

From: Robert Dewar
Sent: Monday, December  6, 2010  10:11 AM

I am having HUGE problems with implementing this aspect, and finally had to give
up in a certainly sense.

The trouble is that the aspect expression is resolved with the type to which the
aspect is applied.

Normally for an aspect like Size, specifying an aspect:

   type R is ... with Size => S;

corresponds to having an attribute definition

   for R'Size use S;

just before R is frozen. Now for this to be OK, we can't have S be an expression
that freezes R, for instance, we must reject

   For R'Size use R'Component_Size;

Now in the case of Default_Value, the corresponding attribute definition

   for R'Default_Value use expr;

is problematic, since resolving expr with R will in general freeze R.

The only way I found to deal with this was to resolve expr with Any_Integer, and
then convert to type R when it is actually used (I could also check the bounds
after R is frozen).

****************************************************************

From: Tucker Taft
Sent: Monday, December  6, 2010  10:27 AM

Interesting problem.  I suppose there is no great harm in freezing the type,
since you don't really need the default value until you create an uninitialized
object of the type, and that will clearly come after processing the
"Default_Value" aspect specification. From an ordering point of view, it would
tend to force you to handle these sorts of "freezing" aspect specifications
after all the ones that must clearly precede freezing (such as a Size
specification).

If you think about it, the default value for the fields of a record are
generally determinable after the record type is laid out, so this one seems
somewhat similar.

****************************************************************

From: Robert Dewar
Sent: Monday, December  6, 2010  10:43 AM

That would require huge amounts of additional mechanism.
Probably we just won't implement it in this form, since it is too disruptive.

In fact the approach I have, which is to resolve with any integer, and then
check the bounds later, works fine in practice and I don't think we will worry
about marginal cases where the difference is noticable.

****************************************************************

From: Tucker Taft
Sent: Monday, December  6, 2010  11:38 AM

It might be noticeable for an enumeration or real type ;-).

****************************************************************

From: Randy Brukardt
Sent: Monday, December  6, 2010  12:36 PM

I was thinking the same thing. The motivating example for this aspect was

   type Status_Kind is (Unknown, Open, Transmitting, ...) with
        Default_Value => Unknown;

which would not resolve by the approach given here.

But I do think that these can be implemented reasonably easily. The key is to
note that as these have to be static expressions, they can't involve the
creation of any default-initialized objects (no user-defined function calls).
Thus, I would suggest that the best approach would be to handle Default_Value
aspects immediately *after* freezing of the type (but before anything else that
depends on freezing. That is, the only thing done before freezing is to ensure
that the aspect was given before freezing (only necessary if you have a matching
pragma versions). The rest of the processing for Default_Value happens after the
freezing of the type. If there is anything that would be a problem, the checking
for a static expression will catch it.

I wouldn't expect this ordering to require "huge additional mechanisms", because
the resolution and legality checking code can remain untouched (as the type is
already frozen, and we don't care about any freezing detection for this type).
Only the freezing code itself would require some additional ordering.

Hope this helps...

P.S. I was originally concerned about the freezing of these expressions, but the
lack of complaints from Steve Baird convinced me that there was no problem.
Perhaps I'm getting too dependent on Steve. :-)

****************************************************************

From: Robert Dewar
Sent: Monday, December  6, 2010  3:35 PM

> It might be noticeable for an enumeration or real type ;-).

Indeed we have to do something special there. This is a huge pain. For now I am
just abandoning Default_Value entirely. Maybe next year :-(

****************************************************************

From: Robert Dewar
Sent: Monday, December  6, 2010  3:39 PM

> I was thinking the same thing. The motivating example for this aspect
> was
>
>     type Status_Kind is (Unknown, Open, Transmitting, ...) with
>          Default_Value =>  Unknown;
>
> which would not resolve by the approach given here.

It's very fundamental to the GNAT approach for aspects that they be translatable
to a pragma or attribute definition clause which can be inserted at the
appropriate point. This works fine for all aspects except Current_Value, and
putting in a whole different mechanism for this one aspect is infeasible.

In fact I believe that Bob was suggesting that the attribute Default_Value be
added to the standard. This suggestion is probably a bad idea, since I certainly
don't see how you would use the attribute definition clause.

> I wouldn't expect this ordering to require "huge additional
> mechanisms", because the resolution and legality checking code can
> remain untouched (as the type is already frozen, and we don't care
> about any freezing detection for this type). Only the freezing code
> itself would require some additional ordering.

Well it does, so for now I am just abandoning trying to implement this aspect,
it won't be in GNAT in 2011, it might be there in 2012, but I doubt it, it's
just too much trouble to implemenyt.

> Hope this helps...

Not enough :-(

****************************************************************

From: Jean-Pierre Rosen
Sent: Monday, December  6, 2010  3:59 PM

> In fact I believe that Bob was suggesting that the attribute
> Default_Value be added to the standard. This suggestion is probably a
> bad idea, since I certainly don't see how you would use the attribute
> definition clause.

But what about a pragma? After all, such a pragma gives a special value to
something that (without the pragma) can be any value. So a pragma is not
inappropriate, and it could appear right after freezing.

****************************************************************

From: Ed Schonberg
Sent: Tuesday, December  7, 2010  7:40 AM

> Indeed we have to do something special there. This is a huge pain. For
> now I am just abandoning Default_Value entirely.
> Maybe next year :-(

For numeric types the default value cannot involve any entity of the type (we
can agree to forbid attributes) and given that it must be a static value it can
be resolved by itself, with its own type (determinable in the first pass of
analysis, or just universal).  So I don't see the problem of resolving the
expression at the point of the aspect itself.  Any subsequent use of the default
involves an unchecked conversion to the type, and those can only occur after the
type is frozen.

For enumeration types we need some special mechanism to make the literals
visible, because it's attractive to use a literal of the type as the default.
Doesn't seem too hard either.

****************************************************************

From: Bob Duff
Sent: Tuesday, December  7, 2010  9:17 AM

> > In fact I believe that Bob was suggesting that the attribute
> > Default_Value be added to the standard. This suggestion is probably
> > a bad idea, since I certainly don't see how you would use the
> > attribute definition clause.

This was in a phone conversation between me and Robert, where Robert was talking
about turning a Default_Value clause into a Default_Value pragma.  I suggested
using an attribute instead of a pragma, not so you can use an attribute
definition clause, but so you can query it.  You can't query a pragma.

My thinking was that this:

    T_Default : constant T := ...;
    type T is ... with Default_Value => T_Default;

    ... T_Default ... -- refer to it

has to be illegal (no matter what order you write it), because of visibility and
freezing rules.  And that's unfortunate, because you might want to refer to that
default value without repeating the expression.

If it's an attribute, you could say:

    type T is ... with Default_Value => ...;

    ... T'Default_Value ... -- refer to it

> But what about a pragma? After all, such a pragma gives a special
> value to something that (without the pragma) can be any value. So a
> pragma is not inappropriate, and it could appear right after freezing.

You mean a pragma that is also an aspect, or just a pragma totally unrelated to
the aspect syntax?

It's a little tricky either way, because I assume you'd either want to forbid
creating objects before the pragma, or make them have a default based on a later
pragma.

But since it's static, there's got to be some way to implement this without
standing on our heads!

On the other hand, I'm not going to cry if this feature doesn't get into Ada
2012.

****************************************************************

From: Bob Duff
Sent: Tuesday, December  7, 2010  9:21 AM

> For enumeration types we need some special mechanism to make the
> literals visible, because it's attractive to use a literal of the type
> as the default. Doesn't seem too hard either.

So are you saying that it has to be a literal, so this:

    type Color is (Red, Orange) with
        Default_Value => Color'Succ(Color'First);

is illegal?  Reminds me of annoying restrictions in Pascal.
But I suppose if it makes the thing implementable, such a restriction is OK.
Maybe we should say "shall be a literal", rather than letting people deduce that
fact from freezing and other rules.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  9:36 AM

> But what about a pragma? After all, such a pragma gives a special
> value to something that (without the pragma) can be any value. So a
> pragma is not inappropriate, and it could appear right after freezing.

I am actually researching the issue of simply allowing the rep clause to appear
AFTER the freezing point in this case, which is not so unreasonable here. Not
much differene between a representation pragma and a attribute clause, the issue
in both cases is whether they have to come before the freeze point.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  9:39 AM

...
> is illegal?  Reminds me of annoying restrictions in Pascal.
> But I suppose if it makes the thing implementable, such a restriction
> is OK.  Maybe we should say "shall be a literal", rather than letting
> people deduce that fact from freezing and other rules.

How about my idea of simply allowing this after the freeze point. We can make
object declarations preceding the attribute definition clause (which can't
happen of course for the aspect syntax) illegal, seems MUCH simpler than trying
to reach back and retrofit a default declared later.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  9:40 AM

Actually here is another idea

   for J'Default_Value use bla;

Cannot appear after J is frozen
Always freezes J
Analyzes bla after freezing J

So you can even have

   for J'Default_Value use J'Size;

odd, but why not

   for J'Default_Value use J'Default_Value;

has to be diagnosed, but this is truly
marginal anyway.

****************************************************************

From: Jean-Pierre Rosen
Sent: Tuesday, December  7, 2010  9:43 AM

> I am actually researching the issue of simply allowing the rep clause
> to appear AFTER the freezing point in this case, which is not so
> unreasonable here. Not much differene between a representation pragma
> and a attribute clause, the issue in both cases is whether they have
> to come before the freeze point.

The whole issue is that this is an aspect of the type which is not a
/representation/ aspect. That's why it has nothing to do with freezing.

My simple model (but I don't know the internals of the compiler) is that if you
specify pragma Default_Value (<blah>), everything within the scope of the pragma
would use the default. Too bad for variables declared before the pragma.

If the aspect is given with an aspect clause, then it is as if the pragma
appeared right after the freezing point.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  9:48 AM

> My simple model (but I don't know the internals of the compiler) is
> that if you specify pragma Default_Value (<blah>), everything within
> the scope of the pragma would use the default. Too bad for variables
> declared before the pragma.

I do not like being able to specify this pragma anywhere, I think the first
argument of the pragma MUST be a local name.

> If the aspect is given with an aspect clause, then it is as if the
> pragma appeared right after the freezing point.

But it is equally easy to do this with an attribute rather than a pragma.

****************************************************************

From: Bob Duff
Sent: Tuesday, December  7, 2010  10:25 AM

> How about my idea of simply allowing this after the freeze point.

OK.

>... We can make object declarations preceding the attribute  definition
>clause (which can't happen of course for the aspect
> syntax) illegal, seems MUCH simpler than trying to reach  back and
>retrofit a default declared later.

The rule is something like, "Before a Default_Val clause for T, it is illegal to declare an object that has a part of type T".  To cover records containing T, and so on.  Same thing for "new ...".

But in this model, when you have aspect syntax, where do you stick in the implicit attribute_defn_clause?

> Actually here is another idea
>
>    for J'Default_Value use bla;
>
> Cannot appear after J is frozen
> Always freezes J
> Analyzes bla after freezing J

OK.

So it's sort of like:

    for J'Default_Value use bla;
                       ^ Freezing point is right there?

And I have the same question as above:
... in this model...where do you stick...?
I guess the answer is just before the first freezing point.  But then you're
inserting a new first freezing point -- a little tricky, but doable, I suppose.

> So you can even have
>
>    for J'Default_Value use J'Size;
>
> odd, but why not
>
>    for J'Default_Value use J'Default_Value;
>
> has to be diagnosed, but this is truly marginal anyway.

And "... use J'Default_Value + 1", and so forth.

****************************************************************

From: Tucker Taft
Sent: Tuesday, December  7, 2010  10:43 AM

I presume this whole discussion is relevant only to GNAT's desire to have an
equivalent pragma or attribute definition.  For those who implement aspect
specifications directly, everything happens at the freezing point or
infinitesimally thereafter.

****************************************************************

From: Bob Duff
Sent: Tuesday, December  7, 2010  10:53 AM

> I presume this whole discussion is relevant only to GNAT's desire to
> have an equivalent pragma or attribute definition.  For those who
> implement aspect specifications directly, everything happens at the
> freezing point or infinitesimally thereafter.

I suppose so.  But for aspects that are also pragmas or attributes, you don't
want to implement them twice -- you want to implement one form in terms of the
other. And for an existing implementation, that means aspects in terms of
pragmas/attributes. (Anybody implementing a new Ada compiler from scratch, these
days?!  ;-))

And for new aspects that do not correspond to language-defined
pragmas/attributes, it makes sense to invent pragmas/attributes just for the
implementation, for uniformity.

So I don't really think this is GNAT-specific.

But I guess something special/non-uniform needs to be done for Default_Value (or
we need to get rid of it, or define it in some other way not involving aspects).

****************************************************************

From: Tucker Taft
Sent: Tuesday, December  7, 2010  11:23 AM

> ... But I guess something special/non-uniform needs to be done for
> Default_Value (or we need to get rid of it, or define it in some other
> way not involving aspects).

Why "not involving aspects"?  What does that accomplish?

****************************************************************

From: Bob Duff
Sent: Tuesday, December  7, 2010 12:00 PM

I was thinking that then it wouldn't involve all the "normal" rules about
freezing re: aspects.  But maybe that's just nonsense -- I don't know.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, December  7, 2010  1:15 PM

> Actually here is another idea
>
>    for J'Default_Value use bla;
>
> Cannot appear after J is frozen
> Always freezes J
> Analyzes bla after freezing J
...

This is definitely a good idea, because it is what I tried to suggest yesterday.
:-)

****************************************************************

From: Randy Brukardt
Sent: Tuesday, December  7, 2010  1:30 PM

> > I presume this whole discussion is relevant only to GNAT's desire to
> > have an equivalent pragma or attribute definition.  For those who
> > implement aspect specifications directly, everything happens at the
> > freezing point or infinitesimally thereafter.
>
> I suppose so.  But for aspects that are also pragmas or attributes,
> you don't want to implement them twice -- you want to implement one
> form in terms of the other.
> And for an existing implementation, that means aspects in terms of
> pragmas/attributes.
> (Anybody implementing a new Ada compiler from scratch, these days?!
> ;-))

I don't buy this. I agree that you don't want to implement them twice, but it's
the internal form drives that, not some particular syntax.

Indeed, for Janus/Ada (which is a classic Dragon Book design), it's impossible
to implement anything with different syntax in the same way, since it is the
syntax that drives the translation. But it is possible to convert both syntaxes
into the same internal form. (Each scope has a list of pending aspect clauses
for unfrozen types.)

Although in this case even that isn't possible, as in the attribute/pragma case
you can resolve everything immediately (and of course the internal form reflects
that), while that is not possible for an aspect clause. So even the internal
forms need to be somewhat different. Of course those forms can share the actual
processing code -- such as handling 'Size, but this is so far separated from the
syntactic forms that they are completely irrelevant.

Moral: never assume *anything* about someone else's implementation. You're
probably wrong. :-)

> And for new aspects that do not correspond to language-defined
> pragmas/attributes, it makes sense to invent pragmas/attributes just
> for the implementation, for uniformity.

Do you insist that your car has a carburetor "for uniformity"? Or a buggy whip
holder?

Pragmas and attributes are obsolete IMHO; no one ought to be using them in new
programs any more than they ought to be using address clauses.

I think Robert's argument about using them in Ada 95/2005 code makes more sense;
it's not about "uniformity", it's about backwards compatibility.

> So I don't really think this is GNAT-specific.

It is. There is no good reason for a 'Default_Value attribute. (And I don't buy
your argument about wanting to read it. For numeric types, a named number works
fine, you don't need a typed constant. For enumerations [which inherently are
named], you are much better initializing with the named literal rather than some
attribute with an unknown value.) A pragma makes more sense, IMHO, but only if
you think that pragmas ought to have these sort of effects. (I hate pragmas.)

> But I guess something special/non-uniform needs to be done for
> Default_Value (or we need to get rid of it, or define it in some other
> way not involving aspects).

All aspects require at least some special processing, so I can't get too worried
about this one being a bit more different than the others.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  2:55 PM

> All aspects require at least some special processing, so I can't get
> too worried about this one being a bit more different than the others.

Actually in GNAT, this is the ONLY aspect that needs special processing, most
aspects just transform into pragmas and attribute definition clauses (most of
which already exist in the language, most of the rest already existed in GNAT,
e.g. precondition, and we just had to invent a few extra ones (e.g. aspect), but
Default_Value is definitely different from all the others, since its placement
and semantics are definitely delicate wrt freezing.

****************************************************************

From: Robert Dewar
Sent: Tuesday, December  7, 2010  2:59 PM

> Pragmas and attributes are obsolete IMHO; no one ought to be using
> them in new programs any more than they ought to be using address clauses.

Nonsense, it is often appropriate to have pragmas and attributes in the private
part, since they are none of the clients business, e.g. pragma Inline, and
aspects don't handle this case. Fine if you prefer to use aspects, but please
don't impose this usage view on others, no more than you should impose your
peculiar anti-use views on others.

I would strongly oppose moving the pragmas and attributes to annex J, not that
it has any effect, but becuase it smacks of trying to impose your style on
others

> I think Robert's argument about using them in Ada 95/2005 code makes
> more sense; it's not about "uniformity", it's about backwards compatibility.
>
>> So I don't really think this is GNAT-specific.
>
> It is. There is no good reason for a 'Default_Value attribute. (And I
> don't buy your argument about wanting to read it. For numeric types, a
> named number works fine, you don't need a typed constant. For
> enumerations [which inherently are named], you are much better
> initializing with the named literal rather than some attribute with an
> unknown value.) A pragma makes more sense, IMHO, but only if you think
> that pragmas ought to have these sort of effects. (I hate pragmas.)

I think the 'Default_Value attribute is indeed useful, in a case where you want
to initialize with a safe value, but do not want to specify a local value
different from the standard default.

****************************************************************

From: Jean-Pierre Rosen
Sent: Tuesday, December  7, 2010  3:24 PM

> (Anybody implementing a new Ada compiler from scratch, these days?!
> ;-))

There might be. See the Tendra project (http://www.ten15.org/), but the site
seems to be down currently.

TBH, I see this project as having as many chances of succeeding as the many
Ada-only OSes everybody is dreaming of...

****************************************************************

From: Arnaud Charlet
Sent: Wednesday, December  8, 2010  2:18 AM

> There might be. See the Tendra project (http://www.ten15.org/), but
> the site seems to be down currently.

This seems to be a C compiler though:

<<
TenDRA is a C compiler, with C++ STL support forthcoming.
>>

****************************************************************

From: Bob Duff
Sent: Wednesday, December  8, 2010  12:52 PM

If you look over on the right-hand side of the page, there's something about
Ada, which you can click on.

****************************************************************

From: Jean-Pierre Rosen
Sent: Thursday, December  9, 2010  1:24 AM

"Ada compiler" is in the box to the right.

****************************************************************

From: Robert Dewar
Sent: Thursday, December  9, 2010  2:57 AM

I am making some progress by treating Current_Value differently and NOT having a
pragma or attribute definition clause.

It is interesting that the work on Default_Value has been approximately similar
to the work on all other aspects combined :-(

****************************************************************

From: Robert Dewar
Sent: Sunday, December 12, 2010  6:41 AM

First, I have finally managed to implement this by abandoning having a
corresponding pragma or attribute, a little inconsistent in the GNAT
environment, but no big deal.

But now, some musings

First of all, a methodological issue, I see two reasons for using Current_Value:

a) avoid non-deterministic behavior from using uninitialized variables, a
   variant on Normalize_Scalars (which doesn't work so well in practice, because
   of the requirement for partition wide consistency).

b) provide initial values that are used by the program.

I am not quite clear on which is the intended use. I am a little concerned about
a), why?

Because reference to uninitialized variables is a major source of bugs, and
usage like a) can actually hide such problems and work against finding them.

Why? Because it disables the use of pragma Initialize_Scalars in GNAT, a
super-valuable tool in finding UI references.

In GNAT, IS initializes all scalars and you can control at bind time or even
execution time what the initial value is. By changing the initial value, and
seeing if the behavior of the program changes, you can find UI references.

Not really a language issue, as the subject says, more like methodological
musings.

Second point, Default_Component_Value has to be used with care. If you play the
trick of giant virtual arrays which are not committed till used, you can really
mess things up using this aspect. Again a methodological issue. I think there
are special ways of avoiding this effecct in some OS's with zero initial values,
to be investigated.

****************************************************************

From: Randy Brukardt
Sent: Monday, December 13, 2010  10:49 PM

...
> I am not quite clear on which is the intended use.

I can't speak for everyone, but my thinking was that this feature would be
useful in two cases:
(1) Where there is a natural value to use as the initial value of all objects of
    the type (for instance, when an enumeration includes a literal like
    "unknown"); and
(2) When the initial value is set out-of-range for a type, to ensure that all
    objects are initialized.

(1) is pretty much your case (b), although of course it also has the effect of
    eliminating non-deterministic behavior.
(2) is mostly about your case (a); but it avoids the non-deterministic behavior
    by replacing it by an exception.

One could also use it to initialize values to an in-range value (what I think
you suggested as case (a)), but that seems like a good way to cover up bugs. (I
recall one Robert Dewar complaining about such features at the outset of the
discussion that led to this proposal.) So I don't consider that an important
usage.

> I am a little concerned about a), why?
>
> Because reference to uninitialized variables is a major source of
> bugs, and usage like a) can actually hide such problems and work
> against finding them.

That's true assuming that the initial value is valid for the first subtype; if
it is *not* valid for the first subtype, then it will always raise an exception
and surely that won't allow any bugs to be hidden. (But it also will cause false
positives in some cases.)

> Why? Because it disables the use of pragma Initialize_Scalars in GNAT,
> a super-valuable tool in finding UI references.
>
> In GNAT, IS initializes all scalars and you can control at bind time
> or even execution time what the initial value is.
> By changing the initial value, and seeing if the behavior of the
> program changes, you can find UI references.
>
> Not really a language issue, as the subject says, more like
> methodological musings.

Right. I can imagine a style guide having fairly significant guidelines about
the use of these aspects.

> Second point, Default_Component_Value has to be used with care. If you
> play the trick of giant virtual arrays which are not committed till
> used, you can really mess things up using this aspect. Again a
> methodological issue. I think there are special ways of avoiding this
> effecct in some OS's with zero initial values, to be investigated.

Right again, but of course this isn't new. You can have the same problem (in any
version of Ada) with an access component or a component of a record type where
one or more components have a default initialization. Indeed, that happened to
me with my Freecell solver years ago -- initializing 2 GB of memory on a 512K
machine was not the best use of execution time! I had to get rid of the implicit
initializations. These aspects (both of them, in fact) provide new ways to cause
this existing problem. Can't get very excited about that.

****************************************************************

From: Bob Duff
Sent: Tuesday, December 14, 2010  8:45 AM

> I can't speak for everyone, but my thinking was that this feature
> would be useful in two cases:
> (1) Where there is a natural value to use as the initial value of all
> objects of the type (for instance, when an enumeration includes a
> literal like "unknown"); and
> (2) When the initial value is set out-of-range for a type, to ensure
> that all objects are initialized.

I agree with Randy about the intended purpose of the feature.

When you put it that way, it seems clear that it isn't the purpose to hide bugs!
;-)

Or to put it another way, if you might wrap the scalar in a record, just so you
can default-initialize it, the purpose of the feature is to avoid the wrapping.
This is independent of the question of whether it is wise to have a default for
that type.

And that wrapping can be extremely painful in my experience -- the code is
filled with "X.Thing" (bad), and "(Thing => X)" (worse) obscuring the code that
does useful work.

****************************************************************

Questions? Ask the ACAA Technical Agent