Version 1.11 of ais/ai-00381.txt
!standard 13.12 (4) 05-05-05 AI95-00381/05
!standard 13.12.1 (1)
!class amendment 04-06-08
!status Amendment 200Y 04-06-29
!status ARG Approved 10-1-0 05-04-16
!status work item 05-03-28
!status WG9 approved 04-11-18
!status ARG Approved 11-0-1 04-06-17
!status work item 04-06-08
!status received 04-06-08
!priority Medium
!difficulty Easy
!subject New Restrictions identifier No_Dependence
!summary
A new Restrictions identifier is proposed to specify that there are no
dependences on a given library unit.
!problem
There are a number of Restrictions identifiers provided for disallowing
dependence on one language-defined unit or another. Rather than
adding more of these identifiers piece-meal, it would make sense to
have a general No_Dependence restriction, identifying the restricted
unit by the expression associated with the restriction.
!proposal
(See wording.)
!wording
Change 13.12(4) to:
restriction ::= restriction_identifier
| restriction_parameter_identifier => restriction_parameter_argument
restriction_parameter_argument ::= name | expression
new section 13.12.1:
13.12.1 Restriction No_Dependence
Static Semantics
The following restriction_parameter_identifier is language defined:
No_Dependence
Specifies a library unit on which there are no semantic
dependences.
Legality Rules
The restriction_parameter_argument of a No_Dependence restriction shall be
a name; the name shall have the form of a full expanded name of a library
unit, but need not denote a unit present in the environment.
AARM Ramification: This name is not resolved.
Post-Compilation Rule
No compilation unit included in the partition shall depend semantically
on the library unit identified by the name.
AARM Note: There is no requirement that the library unit actually exist.
One possible use of the pragma is to prevent the use of
implementation-defined units; when the program is ported to a different
compiler, it is perfectly reasonable that no unit with the name exist.
!discussion
This restriction should reduce the need for having a separate restriction
identifier for each potentially interesting language-defined library unit.
We considered using a static string identify the library unit, as this
would allow a "wildcard" notation (like "Ada.Wide_*"), and would require less
changes to the existing language. But it was just too unnatural.
We also considered limiting the name to just language-defined units. This
was rejected because there are very many language-defined units
(Numerics.Long_Long_Long_Long_Long_Long_Complex_Types is a language-defined
unit, although it's unlikely that any implementation would have one), so there
would a considerable burden to check that the unit is in fact a
language-defined one.
In addition, the restriction is very useful for eliminating dependence on
implementation-defined (and user-defined) library units. For instance, a
GNAT user might use
pragma Restrictions (No_Dependence => GNAT);
to avoid dependence on the GNAT-specific libraries. It makes no sense to force
implementations in invent a similar but different restriction for this purpose.
There is one slightly unpleasant side-effect of allowing any unit. A typo in
the name of a unit might go undetected, because there wouldn't be a dependence
on the badly spelled unit (which is fine). That is essentially the same as
a unit that doesn't exist because it isn't defined by the current
implementation, so there is no way to detect it. But this doesn't seem
important enough to deny a useful capability to users.
!example
pragma Restrictions(No_Dependence => Ada.Command_Line);
-- Example of restriction on language-defined package
!corrigendum 13.12(4)
Replace the paragraph:
restriction ::= restriction_identifier
|
restriction_parameter_identifier = expression>>
by:
restriction ::= restriction_identifier
|
restriction_parameter_identifier = restriction_parameter_argument>>
restriction_parameter_argument ::= name | expression
!corrigendum 13.12.1(1)
Insert new clause:
Static Semantics
The following restriction_parameter_identifier is language defined:
- No_Dependence
-
Specifies a library unit on which there are no semantic dependences.
Legality Rules
The restriction_parameter_argument of a No_Dependence restriction shall be
a name; the name shall have the form of a full expanded name of a
library unit, but need not denote a unit present in the environment.
Post-Compilation Rules
No compilation unit included in the partition shall depend semantically
on the library unit identified by the name.
!ACATS test
An ACATS test should be created for this pragma.
!appendix
From: Tucker Taft
Sent: Monday, June 7, 2004 11:48 PM
Here is my last homework assignment (I hope, and probably
so do you ;-). It is a proposal to add a restriction-parameter
identifier "No_Dependence" whose expression is a static string
identifying a language-defined or implementation-defined
library unit. No compilation unit in the partition may
have a semantic dependence on this library unit.
I chose to use a static string rather than an unquoted
name to conform to the basic syntax of
restriction_parameter_identifier => expression
This decision is debatable. See the !discussion for
a bit more rationale.
****************************************************************
From: Robert A Duff
Sent: Wednesday, June 9, 2004 10:30 AM
I don't care much one way or the other, but I suspect most users would
find the quotes to be superfluous.
Also, I wonder whether the string can contain blanks and other
whitespace:
pragma Restrictions
(No_Dependence => "Ada. " & ascii.nl & " Command_Line");
I don't want to clutter the RM with rules forbidding such.
But when it comes to ascii.nl, whether that's whitespace might
be considered implementation dependent.
Does "Ada.Command_Line -- comment" correspond to a full expanded name?
Syntactically using a 'name' avoids worrying about such silliness.
I realize it might complicate the wording.
****************************************************************
From: Robert Dewar
Sent: Thursday, December 23, 2004 5:16 PM
It seems a big mistake to me to limit this to predefined language
units. The result is that
a) it is far less useful than it would be if it lacked this
arbitrary restriction.
b) it is a pain to implement. We will need to build a complete
list of language defined units for no other purpose than to verify
this silly limitation.
For example, the language allows the implementor to add grand children
to the Ada hierarchy, but such units cannot be mentioned in this
restriction pragma.
Makes absolutely zero sense to me, and there is no hint in the writeup
of where this limitation comes from.
I think that the rule should simply be that the expression is the
fully qualified name of a library unit, and that you are not allowed
to depend on this library unit. Period.
****************************************************************
From: Pascal Leroy
Sent: Monday, December 27, 2004 9:05 AM
This was discussed extensively at the Palma meeting, although I must say
that, re-reading the minutes, I don't think we captured the discussion
very well.
One problem is that this pragma is somewhat paradoxical: you have to
resolve the unit name, and the name resolution entails a semantic
dependence; then, you need to check that you don't have a semantic
dependence on the unit whose name you just resolved. One implementer in
particular (Tuck) was concerned that this would wreak havoc in their name
resolution process.
A second problem is that it is hard to decide what to do if the name
doesn't resolve. Say that a piece of code compiled with GNAT has a pragma
Restrictions (No_Dependence, GNAT), something which sounds useful from the
portability standpoint. Now say that you compile this same code with
Apex. What should happen? First option is: the pragma is rejected
because there is no unit named GNAT; this is kind-of silly as it requires
that the user create empty units for all the stuff that they intend not to
use. Second option is: the pragma is just ignored; this is equally silly,
because then typos are silently ignored, and the pragma really doesn't
guarantee anything.
All of this sounded very unappealing, so we decided to restrict ourselves
to the predefined units because they are sure to exist, and it is easy to
cheat and do a table lookup instead of a full-fledged name resolution.
True, this requires that you have a table of all the predefined unit
names, but that's no big deal, and it's less unpleasant than the
alternatives.
As usual, implementers may add their own restrictions, and maybe something
like No_GNAT_Dependence or No_Apex_Dependence makes sense (with semantics
tailored to the idiosyncrasies of each compiler).
****************************************************************
From: Robert Dewar
Sent: Monday, December 27, 2004 9:34 AM
> All of this sounded very unappealing, so we decided to restrict ourselves
> to the predefined units because they are sure to exist, and it is easy to
> cheat and do a table lookup instead of a full-fledged name resolution.
> True, this requires that you have a table of all the predefined unit
> names, but that's no big deal, and it's less unpleasant than the
> alternatives.
My implementation does not do name resolution at all. No such name
resolution is required for a pragma, the argument just has to have
the form of an expression. Then the binder checks that this unit is
not included in the partition. A trivial implementation.
And yes, a full table of all predefined names *is* a big deal, it is
used ONLY for this silly purpose, and it is a pain to maintain.
> As usual, implementers may add their own restrictions, and maybe something
> like No_GNAT_Dependence or No_Apex_Dependence makes sense (with semantics
> tailored to the idiosyncrasies of each compiler)
I would just add something like "No_Unit" and implement it as above,
"No_GNAT_Dependence" seems plain silly.
Well if this is approved as is, I suppose we might possibly bother
to do the work to implement this annoying limitation. I somewhat
doubt it, given that validation these days is unimportant this
may be one of the points at which we just implement a superset
of Ada 2005 and don't worry about it much.
****************************************************************
From: Randy Brukardt
Sent: Tuesday, December 28, 2004 7:54 PM
Robert Dewar wrote:
> It seems a big mistake to me to limit this to predefined language
> units. The result is that
>
> a) it is far less useful than it would be if it lacked this
> arbitrary restriction.
>
> b) it is a pain to implement. We will need to build a complete
> list of language defined units for no other purpose than to verify
> this silly limitation.
>
> For example, the language allows the implementor to add grand children
> to the Ada hierarchy, but such units cannot be mentioned in this
> restriction pragma.
I agree with Robert on this one. Perhaps that is because I missed the
discussion in Palma that decided to add this limitation. From looking at the
minutes, it seems to be more of a decision from exhaustion rather than one
of good sense.
The name resolution issue that Pascal mentions seems to be more of a problem
with some implementations pragma processing than a real one. Pragma contents
should be lexed and parsed (in a very elementary way) and nothing more.
Everything else is special cased. "On" and "Off" certainly don't resolve in
any way -- there is no requirement that such identifiers are visible
anywhere in the environment, and it seems likely that an implementation with
such a requirement would have issues if indeed they are used as identifiers.
Pascal goes on to say:
> A second problem is that it is hard to decide what to do if the name
> doesn't resolve. Say that a piece of code compiled with GNAT has a pragma
> Restrictions (No_Dependence, GNAT), something which sounds useful from the
> portability standpoint. Now say that you compile this same code with
> Apex. What should happen? First option is: the pragma is rejected
> because there is no unit named GNAT; this is kind-of silly as it requires
> that the user create empty units for all the stuff that they intend not to
> use. Second option is: the pragma is just ignored; this is equally silly,
> because then typos are silently ignored, and the pragma really doesn't
> guarantee anything.
This seems like more of a problem, and its very unfortunate that it is not
mentioned in the minutes. (Probably Tucker was explaining it rather than
recording it; a problem I know well...) Still, this seems like a weak reason
to prevent a useful and obvious capability. The first option seems to be a
red herring; it wouldn't make sense for the pragma to generate an error as
the unit that doesn't exist isn't included in the partition as required.
What could possibly be the problem? Typos are often a problem with pragmas,
and I can't get too excited about that.
If the limitation to language-defined is retained, we should at least name
this restriction so it is clear that it isn't generally useful. Something
like
"No_Predefined_Dependence" or "No_Dependence_on_Predefined" would be better
than a name that promises a general capability but doesn't deliver it. (And
I certainly don't want to encourage implementations to ignore an
arbitrary-seeming limitation.)
So I vote to reconsider this limitation. (Any second for this motion to get
it onto the Paris agenda??)
****************************************************************
From: Robert A. Duff
Sent: Tuesday, December 28, 2004 8:19 PM
> So I vote to reconsider this limitation. (Any second for this motion to get
> it onto the Paris agenda??)
OK, second.
I won't be in Paris to discuss it, but I agree with Randy and Robert.
I think the wording should make it clear that there is no name
resolution (or visibility) going on here. It's just a sequence of
tokens. It's sort of like the "A.B" in "end A.B;" -- visibility and
name resolution do not apply there. Applying name resolution
here is nonsensical, as Pascal says:
> One problem is that this pragma is somewhat paradoxical: you have to
> resolve the unit name, and the name resolution entails a semantic
> dependence; then, you need to check that you don't have a semantic
> dependence on the unit whose name you just resolved.
> One implementer in
> particular (Tuck) was concerned that this would wreak havoc in their name
> resolution process.
Sorry Tuck. ;-) What's the big deal? Am I missing something?
Pascal's concern about ignoring typo's is a real issue.
I don't see any way around that -- I suggest we live with it.
> we decided to restrict ourselves
> to the predefined units because they are sure to exist
That's not quite true. It seems that applying the pragma to
Numerics.Long_Long_Long_Long_Complex_Elementary_Functions ought to be
legal on all implementations, even those that don't support that Annex,
and even those that do, but have no Long_Long_Long_Long_Float.
****************************************************************
From: Tucker Taft
Sent: Tuesday, December 28, 2004 8:49 PM
I'm sorry the minutes don't capture the discussion.
It went on for quite a while, and my objection was
not particularly important. The real problem was
defining the semantics. If I remember correctly,
Pascal objected pretty strongly to just filing away
the strings mentioned in this pragma, and then checking
any unit in the partition against the string at link-time.
That seems well defined, but it means that any (syntactically
acceptable) string whatsoever is permitted, so clearly no
compile-time checking other than syntax can be performed. If I
remember correctly, that rubbed several people the
wrong way.
There didn't seem to be any well-defined point between
a syntax-only check, and a limitation to language-defined
units. Personally I could accept the syntax-only check
(at compile-time). It does sound like it ought to be
reopened, but I believe the normal etiquette is that
someone who voted *for* it needs to reopen the vote.
Thus far we have three people who weren't even present
for the vote...
****************************************************************
From: Robert A. Duff
Sent: Tuesday, December 28, 2004 9:08 PM
> There didn't seem to be any well-defined point between
> a syntax-only check, and a limitation to language-defined
> units.
I agree with that reasoning. I think I prefer the syntax-only check,
despite the error-pronedness.
> It does sound like it ought to be
> reopened, but I believe the normal etiquette is that
> someone who voted *for* it needs to reopen the vote.
Oh, yeah, sorry.
****************************************************************
From: Randy Brukardt
Sent: Tuesday, December 28, 2004 9:28 PM
> There didn't seem to be any well-defined point between
> a syntax-only check, and a limitation to language-defined
> units. Personally I could accept the syntax-only check
> (at compile-time). It does sound like it ought to be
> reopened, but I believe the normal etiquette is that
> someone who voted *for* it needs to reopen the vote.
> Thus far we have three people who weren't even present
> for the vote...
I think we may have to suspend "normal etiquette" in this case. It depends on
what you consider voting "for" the proposal. If you take the straw poll (the
only direct consideration of the limitation), it had a vote of 4-0-5 -- and it
would be hard to say who those four are. And it would hardly be fair to say
that the people who abstained shouldn't be able to change their minds and
decide that they should have voted differently.
OTOH, if you take the final vote for the AI (11-0-1), that happened later in
the meeting and I was there for that vote. (Tucker had to redo some wording or
something.) I recall asking about the limitation to language-defined units and
being told to shut up, we already discussed that. (And thus we already couldn't
give a good description of why we need such a limitation.) Since I was at that
vote, and presumably voted for it (we don't generally record who abstained, and
I don't remember who abstained), I should be able to ask for reconsideration.
Right?
****************************************************************
From: Robert Dewar
Sent: Tuesday, December 28, 2004 9:44 PM
> This seems like more of a problem, and its very unfortunate that it is not
> mentioned in the minutes. (Probably Tucker was explaining it rather than
> recording it; a problem I know well...) Still, this seems like a weak reason
> to prevent a useful and obvious capability. The first option seems to be a
> red herring; it wouldn't make sense for the pragma to generate an error as
> the unit that doesn't exist isn't included in the partition as required.
> What could possibly be the problem? Typos are often a problem with pragmas,
> and I can't get too excited about that.
I agree, if you say
pragma No_Dependence (Rubbish_Name_Nowhere_In_Sight);
then all we need to ensure is that there is no unit
Rubbish_Name_Nowhere_In_Sight in the closure of the partition. Whether or not
this unit is available somewhere in the current compilation system (or indeed
any other compilation system) is irrelevant to the issue of whether or not
there is a dependence in the partition!
> So I vote to reconsider this limitation. (Any second for this motion to get
> it onto the Paris agenda??)
I definitely think it should be rediscussed. I plan to do the simpler
implementation without a list of predefined units that is more general, in that
it allows arbitrary unit names. It will take a lot of convincing that GNAT
should go to a lot of extra implementation effort to restrict this feature to
make it far less useful :-)
****************************************************************
From: Robert Dewar
Sent: Tuesday, December 28, 2004 9:46 PM
> Pascal's concern about ignoring typo's is a real issue.
> I don't see any way around that -- I suggest we live with it.
Well if anyone is that worried about it, there is no reason why you
can't go searching around for the unit name, and if you cannot find
any sign of it, but you can find a close misspelling, then generate
a warning. Personally I do not find this worth while.
> That's not quite true. It seems that applying the pragma to
> Numerics.Long_Long_Long_Long_Complex_Elementary_Functions ought to be
> legal on all implementations, even those that don't support that Annex,
> and even those that do, but have no Long_Long_Long_Long_Float.
Indeed, another indication that the restriction is ill-formed in any
case.
****************************************************************
From: Robert Dewar
Sent: Tuesday, December 28, 2004 9:53 PM
> If I remember correctly, that rubbed several people the wrong way.
What is the technical objection here? "being rubbed the
wrong way" is not a technical objection!
> There didn't seem to be any well-defined point between
> a syntax-only check, and a limitation to language-defined
> units. Personally I could accept the syntax-only check
> (at compile-time). It does sound like it ought to be
> reopened, but I believe the normal etiquette is that
> someone who voted *for* it needs to reopen the vote.
> Thus far we have three people who weren't even present
> for the vote...
Well it is always in order to introduce a new motion to undo
the effect of an earlier one :-)
So far I have seen no good technical arguments for the AI
as written.
The "syntax only" approach has two real advantages:
1. It's easier to implement (anyone objecting to this, please
explain why you think otherwise, how can you possibly do normal
name resolution for a name that is not only NOT in sight, but
is not allowed to be in sight), and making a list of all
predefined units is a real pain.
2. It's far more useful. As Pascal points out, a GNAT user could
easily find
pragma Restrictions (No_Dependence => GNAT);
useful to ensure no dependence on GNAT specific packages
****************************************************************
Questions? Ask the ACAA Technical Agent