Version 1.4 of ai12s/ai12-0389-1.txt

Unformatted version of ai12s/ai12-0389-1.txt version 1.4
Other versions for file ai12s/ai12-0389-1.txt

!standard 13.1.1(38/3)          20-09-09 AI12-0389-1/02
!standard 13.12.1(6.3/3)
!class Amendment 20-08-31
!status Amendment 1-2012 20-09-09
!status WG9 Approved 22-06-22
!status ARG Approved 12-1-1 20-09-09
!status work item 20-08-31
!status received 20-07-23
!priority Low
!difficulty Easy
!subject Ignoring unrecognized aspects
!summary
Implementations are granted permission to ignore specifications of unrecognized aspects. Two new restrictions, No_Unrecognized_Aspects and No_Unrecognized_Pragmas, are defined.
!problem
Ada allows an implementation the freedom to ignore an unrecognized pragma (see ARM 2.8(15)), but does not grant such a freedom in the case of a specification of an unrecognized aspect (see AARM 13.1.1(38.a/3)).
It would be useful to allow such freedom for aspect specifications for much the same reasons that it is useful for pragmas.
!proposal
(See Summary.)
!wording
Add after 13.1.1(38/3) (in the Implementation Permissions section)
An implementation may ignore the specification of an unrecognized aspect; if an implementation chooses to ignore such an aspect specification (as opposed to rejecting it), then it has no effect on the semantics of the program except for possibly (and this is not required) the rejection of syntax errors within the aspect_definition.
AARM note: Identifying the textual end of an aspect_definition for an unrecognized aspect may be challenging, particularly if the syntax for the unrecognized aspect's aspect_definition is implementation-defined. It is not specified how an implementation might accomplish this. Note that an implementation is never required to be able to do this; if an aspect_definition for an unrecognized aspect is problematic in any way, then it can always be rejected (as opposed to being ignored).
Delete from AARM 13.1.1(38.a/3)
Unrecognized aspects are illegal whether or not they use custom syntax, so this freedom does not reduce portability.
Replace AARM 13.14(19.k)
2.8 overrides the freezing rules in the case of unrecognized pragmas.
with
2.8 overrides the freezing rules in the case of an unrecognized pragma; similarly 13.1.1 overrides the freezing rules in the case of a specification of an unrecognized aspect.
Append after 13.12.1(6.3/3) (as part of the list of restriction identifiers)
No_Unrecognized_Aspects
There are no aspect_specifications having an unrecognized aspect_identifier. This restriction applies only to the current compilation or environment, not the entire partition.
AARM Ramification: When this restriction is in effect, unrecognized aspects cannot be ignored in the current compilation; they violate the restriction. This is true despite the Implementation Permission of 13.1.1.
No_Unrecognized_Pragmas
There are no pragmas having an unrecognized pragma identifier. This restriction applies only to the current compilation or environment, not the entire partition.
AARM Ramification: When this restriction is in effect, unrecognized pragmas cannot be ignored in the current compilation; they violate the restriction. This is true despite the rules of 2.8.
!discussion
(See problem.)
!corrigendum 13.1.1(38/3)
Insert after the paragraph:
Implementations may support implementation-defined aspects. The aspect_specification for an implementation-defined aspect may use an implementation-defined syntax for the aspect_definition, and may follow implementation-defined legality and semantics rules.
the new paragraph:
An implementation may ignore the specification of an unrecognized aspect; if an implementation chooses to ignore such an aspect specification (as opposed to rejecting it), then it has no effect on the semantics of the program except for possibly (and this is not required) the rejection of syntax errors within the aspect_definition.
!corrigendum 13.12.1(6.3/3)
Insert after the paragraph:
No_Use_Of_Pragma
Identifies a pragma which is not to be used.
the new paragraphs:
No_Unrecognized_Aspects
There are no aspect_specifications having an unrecognized aspect_identifier. This restriction applies only to the current compilation or environment, not the entire partition.
No_Unrecognized_Pragmas
There are no pragmas having an unrecognized pragma identifier. This restriction applies only to the current compilation or environment, not the entire partition.
!ASIS
No ASIS effect.
!ACATS test
The ACATS does not test implementation choices, so no tests are needed for the new rule. However, it might be necessary to modify an existing test that expects the rejection of an unknown aspect.
!appendix

From: Steve Baird
Sent: Thursday, July 23, 2020  7:18 PM

Ada allows an implementation the freedom to ignore an unrecognized pragma (see 
ARM 2.8(15)), but does not grant such a freedom in the case of a specification 
of an unrecognized aspect (see AARM 13.1.1(38.a/3)).

It would be useful to relax that restriction in order to make it easier for 
older versions of tools (including, but not limited to, compilers) to be able 
to process newer Ada source code that includes specifications of 
recently-added aspects (language-defined or not).

Aspect specifications are somewhat different than pragmas because 
implementation-defined aspect_definition syntax is permitted 
(see 13.1.1(38/3)). But as with any implementation permission, no new 
requirements are imposed. For example, one implementation might choose to 
ignore this new permission completely while another might choose to take 
advantage of it only in the case of an aspect_definition which has "standard" 
syntax.

There is a related issue having to do with the treatment of syntactically 
incorrect ignored pragmas (see ARM 2.8(15)); presumably definitions of 
unrecognized aspects could be handled similarly.
Interactions with freezing rules would also presumably follow the existing 
model for unrecognized pragmas (see AARM 13.14(19.k)).

One might be concerned about spelling errors. It would be undesirable to 
quietly ignore the aspect definition in
     procedure Foo with In_Line;

A first response to this point is that typically a warning would be generated 
in a situation like this, even if warning generation is not part of the 
language definition. A second is that this is nothing new; we already have 
the same situation with misspelled pragma names, as in
    pragma In_Line (Foo);

One might argue that there is no need for a change here because 
implementations are already allowed, in effect at least, to ignore 
unrecognized aspects. Given the specification of an unrecognized aspect, 
an implementation could claim that in fact the aspect is recognized as an 
implementation-defined pragma which is defined to have no effect. That does 
not seem like the right solution to this problem (the documentation 
requirement associated with M.2(44.1/3) could be finessed, but really?), and 
it seems unnecessarily inconsistent with the treatment of pragmas.

I'm not proposing specific wording here; just broaching the subject.

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

From: Tucker Taft
Sent: Thursday, July 23, 2020  8:01 PM

I support the idea.  Aspects have begun to replace pragmas in many contexts, 
and should have the same nice property of not interfering with the ability of 
the code to compile with compilers or on targets where the aspect is not 
defined or not meaningful.

This also argues for a "good taste in implementation-defined aspects" 
philosophy that we somewhat attempted to define for pragmas.  Namely, an 
implementation-defined aspect should typically not make an illegal program 
legal, but should rather only affect performance, or impose additional 
restrictions that make a legal program illegal.

This is not something we would ever try to enforce, and clearly would defeat 
the purpose of aspects that are designed to enable some "syntactic sugar" for
a particular type.  But it seems something to keep in mind when an 
implementation defines its own aspect.  The goal is that a program using an 
implementation-defined aspect typically remains legal if the aspect is simply
ignored, so it can be compiled by an older or different compiler.

This is also quite consistent with the "generalized aspects" AI (AI12-0355-1), 
where an aspect can be associated with an underlying subsystem, so even the 
compiler doesn't have to really "understand" the aspect specification to 
parse it and pass the information content through to an underlying subsystem 
like OpenMP (or, e.g. CUDA) 
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0355-1.txt).

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

From: Randy Brukardt
Sent: Thursday, July 23, 2020  8:44 PM

I'm cool to this idea.

I am not a fan of the "ignoring unrecognized pragmas" rule in the first place. 
When we were working on Claw, we had a number of instances where someone used 
the wrong version of an implementation-specific unit. Those units spewed 
warnings rather than errors (because of the pragma rule), warnings typically 
don't stop compilations, so usually those would just scroll by when doing a 
build. When the resulting program didn't work, one wasted a lot of time 
tracking down a problem which was just a configuration error. We also had 
cases where impl-def pragmas were misspelled or misapplied and again the 
problem was hard to find.

Aspects (which are always entity-specific) are much more likely to involve a 
property that is critical to the operation of the program, so they are even 
less likely to be a good idea to be ignored.

One of the reasons that I prefer aspects to pragmas is that they don't involve 
the ignoring nonsense.

Tucker mentioned the need for "good taste in implementation-defined aspects". 
Please, no. Most of the impl-def aspects that I've defined to date wouldn't 
meet any such requirements. And I don't think it is reasonable to hamstring 
implementers that way in working out mechanisms to properly check Global use 
for access types and other important issues that will not be solved in 
Ada 202x.

I recall that Robert Dewar was very against the idea of "good taste in 
impl-def pragmas", and I believe he would have felt the same about doing the 
same for aspects.

Without some form of "good taste", ignoring aspects is downright dangerous. 
If someone is worried about portability, then don't use impl-def aspects. 
That doesn't seem that hard to understand.

As Steve points out, ignoring an aspect can be done if the implementation 
recognizes it and treats it as implementation-defined. That seems to me to be 
the right answer, since it is only safe to ignore aspects that you *know* will
not cause problems if ignored. (For instance, Janus/Ada will soon ignore 
Pre/Post if the Assertion_Mode is Ignore, in order to allow using those in 
code even before they get implemented in the compiler. That's pretty safe, 
since they wouldn't be executed anyway, and the only thing that might be 
missed is an illegal precondition expression. But I wouldn't want to do 
anything like that for No_Return.)

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

From: Tucker Taft
Sent: Thursday, July 23, 2020  9:21 PM

Implementations can of course have different modes of behavior with respect to 
implementation-defined or simply unrecognized aspects.  So the question what 
"mode" or "modes" should all compilers support?  There is already a 
restriction No_Implementation_Aspect_Specifications, so either that 
restriction, or another one we could invent for this purpose, could be used 
to provide the protection you want.  In my view, the "Restriction" mechanism 
is kind of the best of both worlds, in that it permits a project that wants to
avoid certain problems to self-impose an appropriate restriction at the library
level, while those projects that appreciate a less strict mode can choose not 
to impose such a restriction.  I think having various standard restrictions is 
better than inventing a different set of command-line parameters for every 
compiler to control its various modes.

So perhaps we should add a pair of standard restrictions for 
No_Unrecognized_Pragmas and No_Unrecognized_Aspect_Specifications to go along 
with loosening the basic rule for aspects to match that of pragmas.

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

From: Richard Wai
Sent: Thursday, July 23, 2020  10:54 PM

I think doing this is obviously orthagonal with pragmas, and you probably all 
know by now how much of a fan I am of orthagonality.

I definitely ran into this problem with some tooling we built that makes use 
of such unrecognized pragmas, where those pragmas are clearly more naturally 
suited to aspects, but that was not an option. It appears arbirary.

I think it is important to mention that “implementation-defined aspect should 
typically not make an illegal program legal, but should rather only affect 
performance, or impose additional restrictions that make a legal program 
illegal." Afterall, it is not as if we are talking about user-defined aspects 
here (as close as AI12-0351-1 may be to that), anyone doing this is making 
some kind of compiler, tooling, or runtime support library, so implementation 
advice at the least seems rational.

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

From: Jean-Pierre Rosen
Sent: Friday, July 24, 2020  1:31 AM

There is a minimum good taste which is necessary, typically:
"implementation-defined aspect should typically not make an illegal program 
legal"

Typically, we don't want:
type Void is null record;
type Universal_Pointer is access Void with C_Can_Point_To_Anything;

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

From: Arnaud Charlet
Sent: Friday, July 24, 2020  1:57 AM

I'm also strongly in favor of this, users can always enable warning-as-error 
and compilers can provide a "picky pedantic" mode where unknown aspects are 
illegal, but in our experience with GNAT, having this capability is very 
important since otherwise it e.g. prevents older versions of GNAT (compiler
or ASIS based tools) to be able to process newer Ada or SPARK source code. 
The example of SPARK specific aspects is a typical case, but some Ada 202x 
aspects also are in this category or desirable to ignore at least in some 
cases.

This also makes it easier for tool developers to experiment with new aspects 
and still be able to compile their code, which is something we want to 
encourage for the Ada ecosystem.

pragmas have always provided this capability (as in other languages), and 
given that we are deprecating most pragmas in favor of aspects these days, 
providing the ability for people to experiment with new aspects is really 
important IMO.

> There is a minimum good taste which is necessary, typically:
> "implementation-defined aspect should typically not make an illegal 
> program legal"

Right, the same is already true for pragmas.

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

From: Bob Duff
Sent: Friday, July 24, 2020  10:08 AM

> I'm also strongly in favor of this,...

I basically agree with Arno.

But this whole argument is based on a delusion held by language designers -- 
we tend to (wrongly) think we can boss people around. ;-) In fact, language 
definitions don't require anybody to do anything. They just define the 
language.

AdaCore is going to do what it decides is best regarding ignoring aspects 
(and everything else). The only possible effect on AdaCore of an unfavorable 
ruling by ARG would be that AdaCore might have a switch so they can honestly 
say GNAT (has a mode in which it) conforms to the RM.
Likewise for other compiler writers.

I strongly object to spending even one nanosecond arguing about what aspects 
are "in good taste".  The job of the RM is to define Ada, not to give advice 
to compiler writers about taste in language extensions.  And if you want to 
turn that advice into requirements, then see above about "delusion".

Restrictions is one of my favorite features, but I don't think Tucker's 
suggested new restrictions are worth the trouble.  I don't strongly object 
to them, though.

As to the "warnings scroll off the screen" problem, that's a general problem 
about warnings (more precisely, diagnostic messages that don't kill the build),
so a solution specific to aspect-related warnings is inappropriate.  Anyway, 
it's an easy problem to solve, and is already solved in GNAT and probably 
other Ada compilers.

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

From: Randy Brukardt
Sent: Saturday, July 25, 2020  7:15 PM

...
> I strongly object to spending even one nanosecond arguing about what
> aspects are "in good taste".  The job of the RM is to define Ada, not to
> give advice to compiler writers about taste in language extensions.  And
> if you want to turn that advice into requirements, then see above about
> "delusion".

Yup. If someone wants to define an aspect No_Accessibility_Check_Nonsense to 
be applied to access types, who are we to say that they can't do that? 
Moreover, the idea that making illegal code legal is somehow more problematic 
than making legal code illegal seems dubious at best.

Richard said something about making Ada more consistent -- but if you're going 
to do that, you'll also have to allow ignoring unrecognized 
attribute_definition_clauses. Somehow, that's never been thought to be a 
good idea during the entire Ada 83 to present timeframe, so I have to wonder 
why it is suddenly a good idea for aspects (many of which replace 
attribute_definition_clauses). Anyway, it won't be more consistent to allow 
ignoring of aspects, it just moves a bump. I hope no one thinks that ignoring 
everything unrecognized is a good idea (my understanding is that the major 
objection to the proposed ghost code idea was the concern that a misspelled 
ghost name would be ignored).

> As to the "warnings scroll off the screen" problem, that's a general
> problem about warnings (more precisely, diagnostic messages that don't
> kill the build), so a solution specific to aspect-related warnings is
> inappropriate.  Anyway, it's an easy problem to solve, and is already
> solved in GNAT and probably other Ada compilers.

Now you're being delusional. GNAT surely does not solve this problem. When 
I compile my code with GNAT, I get bunches of useless warnings about loops 
that only execute once and other similar nonsense. These potentially push 
off useful warnings and also make it much less likely that I will even look
carefully at the messages. In such cases, unrecognized pragma warnings are 
lost. Setting warnings-as-errors does not help, as the useless warnings 
would prevent the compilation of the programs. One can "solve" the problem
by modifying the source code, but then you are making custom versions for 
every compiler -- if you're doing that anyway, you can trivially get rid 
of any inappropriate pragmas.

Ergo, I don't think ignoring pragmas helps anything (and can be very harmful),
and thus I continue to object to expanding it to anything else.

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

From: Tucker Taft
Sent: Saturday, July 25, 2020  9:24 PM

Attributes are different in my mind, because any use of an attribute implies 
you need to know the type of the attribute.  So I don't see much value in 
ignoring unrecognized implementation-defined attributes, since you really 
can't generate code.  And the same will be true for aspect specifications 
that are specifying the value of an implementation-defined attributes, if 
the attribute actually gets referenced.  But there might very likely be 
aspects analogous to pragmas, like "Inline_Always" or "Lock_Free" that are 
useful when understood by a compiler, but not a serious portability problem
if ignored when not recognized.

My view is that we can help the "pragma" issue and not create a bizarre 
incentive to define implementation-defined pragmas when an 
implementation-defined aspect would clearly be preferable, by defining two 
standard restrictions, No_Unrecognized_Pragma and 
No_Unrecognized_Aspect_Specifications, thereby providing the checking folks 
like you prefer for pragmas, and allowing "benign" implementation-defined 
aspects to be treated like pragmas, to further enable the general move away
from pragmas.

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

From: Steve Baird
Sent: Monday, August 31, 2020  5:57 PM

Here is an AI for this one, pretty much just writing up what has already 
been discussed. [This is version /01 of this AI - Editor.]

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

From: Randy Brukardt
Sent: Friday, October 2, 2020  9:52 PM

In this AI, we define a restriction as follows:

  No_Unrecognized_Aspects

  Any aspect_specification having an unrecognized aspect_identifier shall be
  rejected[ (as opposed to being ignored)]. This restriction applies only to
  the current compilation or environment, not the entire partition.

Bob has typically complained about the use of "reject" in normative wording. 
Dunno if he napped through the review of this AI :-), but this is precisely 
the sort of use that he has complained about in the past.

Moreover, this is not the typical form for a restriction, which starts 
something like "There are no ...". Probably it would be better to use 
wording something like:

  There are no aspect_specifications having an unrecognized aspect_identifier;
  they are not ignored. This restriction applies only to
  the current compilation or environment, not the entire partition.

I'm dubious that the part about not ignoring buys anything (at least 
normatively), since "no aspect_identifiers" doesn't depend on whether they're 
ignored. So perhaps drop that and explain in an AARM note that this does not 
allow ignoring aspects:

  There are no aspect_specifications having an unrecognized aspect_identifier. 
  This restriction applies only to the current compilation or environment, not
  the entire partition.

  Ramification: When this restriction is in effect, unrecognized 
  aspect_identifiers cannot be ignored; the Implementation Permission of 
  13.1.1 does not apply.

I'd make a similar change to No_Unrecognized_Pragmas:

  No_Unrecognized_Pragmas
  There are no pragmas having an unrecognized pragma identifier. This 
  restriction applies only to the current compilation or environment, not the 
  entire partition.

If no one objects, I can treat these rewordings as my editorial review of 
this AI.

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

From: Bob Duff
Sent: Saturday, October 3, 2020  6:37 AM

> In this AI, we define a restriction as follows:
> 
>   No_Unrecognized_Aspects
> 
>   Any aspect_specification having an unrecognized aspect_identifier shall be
>   rejected[ (as opposed to being ignored)]. This restriction applies only to
>   the current compilation or environment, not the entire partition.
> 
> Bob has typically complained about the use of "reject" in normative wording.
> Dunno if he napped through the review of this AI :-), ...

Apparently.

> Moreover, this is not the typical form for a restriction, which starts 
> something like "There are no ...". Probably it would be better to use 
> wording something like:
> 
>   There are no aspect_specifications having an unrecognized aspect_identifier;
>   they are not ignored. This restriction applies only to
>   the current compilation or environment, not the entire partition.

OK.

> I'm dubious that the part about not ignoring buys anything (at least 
> normatively), ...

Yeah, that's why it's in square brackets in the original you quoted above.

> ...since "no aspect_identifiers" doesn't depend on whether they're 
> ignored. So perhaps drop that and explain in an AARM note that this 
> does not allow ignoring aspects:
> 
>   There are no aspect_specifications having an unrecognized aspect_identifier.
>   This restriction applies only to the current compilation or environment, not
>   the entire partition.
> 
>   Ramification: When this restriction is in effect, unrecognized 
>   aspect_identifiers cannot be ignored; the Implementation Permission of 
>   13.1.1 does not apply.

I've no opinion whether the non-normative-but-perhaps-informative
part should be moved to the AARM.

> I'd make a similar change to No_Unrecognized_Pragmas:
> 
>   No_Unrecognized_Pragmas
>   There are no pragmas having an unrecognized pragma identifier. This restriction
>   applies only to the current compilation or environment, not the entire partition.
> 
> If no one objects, I can treat these rewordings as my editorial review 
> of this AI.

OK!

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

From: Tucker Taft
Sent: Saturday, October 3, 2020  8:48 AM

Works for me.

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

Questions? Ask the ACAA Technical Agent