Version 1.1 of ai12s/ai12-0245-1.txt

Unformatted version of ai12s/ai12-0245-1.txt version 1.1
Other versions for file ai12s/ai12-0245-1.txt

!standard 10.1.2(3)          18-01-12 AI12-0245-1/01
!class Amendment 18-01-12
!status work item 18-01-12
!status received 15-03-20
!priority Very_Low
!difficulty Easy
!subject "with and use" clause
!summary
Add a "with and use" clause, which is equivalent to "with" followed by "use".
!problem
There sometimes is a duplication in a context clause, as the "with" and "use" clauses name the same package:
with Some_Long_Named_Package; use Some_Long_Named_Package;
This can harm readability if there are a lot of packages that are both "with"ed and "use"d.
!proposal
(See Summary.)
!wording
** TBD.
!discussion
If you're duplicating most of your context items in use clauses, you're using (groan) use clauses wrong. They need to be used judiciously, not as something you write as a matter-of-course.
There is a semantic issue with this definition: "with A.B.C" means "with A, A.B, A.B.C", while "use A.B.C" does not include "use A" or "use A.B". So "with and use A.B.C" has different effects on A and A.B than it has on A.B.C.
One would never want to use this on every context item, as "use" only works on non-generic packages. Therefore, having this available will not make writing context clauses trivial; thought will still be needed.
The original request used the syntax "use with". This syntax was rejected as it puts the less important thing first. Many experienced Ada programmers are used to skipping lines that start with "use" when reading Ada context clauses, as they are irrelevant to the operations available. We would not want a new syntax to require a complete retraining of context clause reading.
Context clause changes are rare during the course of a project, so this syntax saves little writing during the course of a project.
[Editor's rant: use clauses in general should be used in the most restricted scope possible. Moreover, one should use "use type" or "use all type" whenever possible. As such, this syntax is encouraging the worst possible style (using a package use clause in the widest possible scope). That's the wrong message to send to Ada programmers.
My personal style "use"s a very limited number of packages globally throughout a project. These "global use" packages are the same in every package (so the visibility environment is consist in the entire project). This is accomplished by putting these in a pair of separate lines in the context clause:
with Foo, Bar, Ada.Text_IO; use Foo, Bar, Ada.Text_IO;
By pairing up the lines, any mistakes can easily be seen. And these lines are almost never changed after the start of a project, as the set of global packages is not easily changed (all packages ought to be changed if any are). The vast majority of context clause changes involve uses of single routines from a package, which shouldn't involve a use clause in any case.]
!ASIS
Probably need new functions.
!ACATS test
An ACATS C-Test is needed to check that the new capabilities are supported.
!appendix

!topic Request for "use with" clause
!reference Ada 202x
!from Britt Snodgrass 2017-12-02
!keywords use with clause
!discussion

For a number of years I have wished to avoid the need to repeat a package's
name in context clause lines like the following example:

with Some_Long_Named_Package;  use Some_Long_Named_Package;

I would prefer to be able use the following "syntactic sugar" alternative
in any place where the example above is allowed (i.e., package context
clauses):

use with Some_Long_Named_Package;

Here the package name is only needed in one place. Adding/removing the use
clause is simply a matter of adding/removing "use " at the beginning of the
line (where it sorts nicely).

I know this general idea is not new because I found an old discussion thread
on comp.lang.ada that started 2003-10-31. However I have not been able to
locate any related discussion in the Ada Issues database.

Would the following be alternative syntax be feasible in Ada 2020?:

use with Parent.Child;
use limited private with Some_Other_Package;

instead of

with Parent.Child;  use Parent.Child;
limited private with Some_Other_Package;  use Some_Other_Package;

Thank you for considering this.

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

From: Victor Porton
Sent: Sunday, December 3, 2017  8:03 PM

I would vote for.

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

From: John Barnes
Sent: Monday, December 4, 2017  4:01 AM

So would I.

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

From: Randy Brukardt
Sent: Monday, December 4, 2017  2:04 PM

>For a number of years I have wished to avoid the need to repeat a
>package's name in context clause lines like the following example:
>
>	with Some_Long_Named_Package;  use Some_Long_Named_Package;

IMHO, there are two things wrong with this example. First, one ought to put the
use directly below the with so that one can easily see any typos in either:

	with Some_Long_Named_Package;
      use  Some_Long_Named_Package;

(note the extra space after "use"). If somehow these lines end up different,
there is an obvious (to humans) error to be fixed.

Second, giving packages really long names is a bad idea, as almost any package
will contain non-overloadable entities that cause name conflicts. Thus the name
will have to be used as a prefix in at least some usages, and having the name be
rather long impacts readability.

Indeed, because of this effect, I strongly recommend avoiding package use
clauses altogether (with the possible exception of a few commonly used
language-defined packages) and using "use all type" instead. "Use all type" only
makes overloadable entities visible; thus conflicts are almost impossible. That
means that future package maintenance (like adding new functionality) will be
harmless to existing uses, something that is NOT true for package "use".

>I would prefer to be able use the following "syntactic sugar"
>alternative in any place where the example above is allowed (i.e.,
>package context
>clauses):
>
>	use with Some_Long_Named_Package;

I would prefer to see much less use of package "use", and I am strongly opposed
to anything that makes it easier.

Also, there is a semantic issue here for child units: "with" Ada.Text_IO makes
both "Ada" and "Ada.Text_IO" potentially visible; "use" Ada.Text_IO only makes
"Ada.Text_IO" directly visible. So these have subtly different meanings. Having
"use with" work consistently means that:

     use with Ada.Text_IO;

doesn't mean the same thing as:

     with Ada.Text_IO;
     use  Ada.Text_IO;

> Here the package name is only needed in one place.

That's not true in practical programs; you'll need some uses of the package name
to fix conflicts (mostly non-overloadable entities). One extra use hardly harms
readability enough for the effort involved.

In any case, a good program (IMHO) will only contain a single package use in the
context clause (perhaps containing a small number of units). So this proposed
syntax would save only a single line per compilation unit; that's hardly going
to help readability significantly enough for the effort (which is substantial,
if the semantic issue is to be addressed).

Concluding: IMHO, programs that contain a lot of package use clauses are bad
programs, and I have no interest in helping people write bad Ada programs. And
the gain for good programs are minimal (as I showed above, stacking the "with"
and "use" improves the readability to the point of making it ignorable in normal
reading). So I don't see the point; I will be a strong "NO" on this idea.

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

From: Niklas Holsti
Sent: Monday, December 4, 2017  2:37 PM

I am neutral (neither for nor against), but if a combined "with" and "use" is
accepted, I would much prefer the form (which someone proposed earlier, although
perhaps not as formally):

    with and use Foo;

Admittedly there is one more keyword, "and", but I think this form reads better.

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

From: Jean-Pierre Rosen
Sent: Monday, December 4, 2017  7:37 PM

> So would I.

I wouldn't. I am a famous proponent of the use clause, because it allows to open
visibility only where needed. Having a use clause together with the with clause
is a misuse of the feature (except in some cases where the package is needed
everywhere in the unit) that should not be encouraged.

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

From: Britt Snodgrass
Sent: Monday, December 4, 2017  10:41 PM

In response to Randy's initial reply:

I hope to keep the discussion on my proposal focused on syntax and semantics,
and not get sidetracked by individual stylistic preferences and prejudices
(e.g., advisability of package use clauses and same line versus separate line
with/use formatting). I've worked in the language a long time and have my own,
considered style preferences which may be different than the preferences of
others.

Regarding long package names, I generally don't like them either but that is
often out of my control when working with large legacy projects.

For our production code (i.e. shipped to customers), we don't allow any package
use clauses except for a single special package containing project-wide
primitive types. However this is not the only code we write or maintain. When
working with prototype and test support code, I choose to employ use clauses
more liberally.

My "use with" proposal is basically that "use with <pkg_name>;" be conceptually
expanded into "with <pkg_name>; use <pkg_name>" in the limited places that "with
<pkg_name>; use <pkg_name>" is allowed.

Randy makes that point that when the <pkg_name> is that of a child package such
as A.B.C then:

   with A.B.C;
   use  A.B.C;

is equivalent to the verbose expansion:

   with A;     -- A is with'd but not use'd
   with A.B;   -- A.B is with'd but not use'd
   with A.B.C; -- A.B.C is with'd, and
   use  A.B.C; -- A.B.C is also use'd

In my proposal,

   use with A.B.C;

would mean exactly the same thing (same semantics) as the separate with & use,
above. It would be as if I had written the following verbose form:

   with A;
   with A.B;
   use with A.B.C;

where, again, only the grandchild package C is use'd.

If, alternatively, I wanted to also use both A and A.B as well, then I would
have to write three lines as follows:

   use with A;
   use with A.B;
   use with A.B.C;

which is fine, if that's what, I want and is better than writing:

   with A;     use A;
   with A.B;   use A.B;
   with A.B.C; use A.B.C;

Ada 2005, Ada 2012 and draft Ada 202x have already made several allowances for
alternative (though not universally liked) syntax in the interest of brevity,
clarity and marketing.  The "use with" proposal is less radical than some other
syntax changes already made or planned (since Ada 95).

I don't like the old 2003 proposal of "with and use".  It sounds awkward and
would be unsuitable for sorting.

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

From: Pascal Obry
Sent: Tuesday, December 5, 2017  12:15 AM

> I wouldn't. I am a famous proponent of the use clause, because it
> allows to open visibility only where needed. Having a use clause
> together with the with clause is a misuse of the feature (except in
> some cases where the package is needed everywhere in the unit) that
> should not be encouraged.

I agree 100% with Jean-Pierre for the very same reasons.

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

From: John Barnes
Sent: Tuesday, December 5, 2017  2:09 AM

I have had second thoughts. It would require a massive overhaul of my book. I
would be torn between leaving it as it is for the sake of those not yet on Ada
2012 and using it.

And maybe it would encourage confusing maintenance problems.

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

From: Britt Snodgrass
Sent: Tuesday, December 5, 2017  11:06 AM

In response to John's second thoughts, it would be optional, alternative syntax
for Ada 202x so current books would not be affected.

Hypothetically, if "with X; use X;" were replaced with "use with X;" for all
packages X in all existing code and that altered code were recompiled with a
supporting Ada 202x compiler, what would break or behave differently? Can anyone
provide an example?

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

From: Randy Brukardt
Sent: Tuesday, December 5, 2017  3:59 PM

My head? For having a syntax that puts the least important thing ("use") first??
:-)

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

From: Randy Brukardt
Sent: Tuesday, December 5, 2017  4:04 PM

Seriously, unless I'm dealing with a visibility problem, I tend to stop reading
when I see "use", because the rest of the clause is irrelevant to what the code
does. Having something critical ("with") hidden in the middle of a "use" clause
going to make reading Ada harder. To save a single line per compilation unit.

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

From: Randy Brukardt
Sent: Friday, January 12, 2018  8:27 PM

At the risk of tearing the bandage off of this old scab...

>Would the following be alternative syntax be feasible in Ada 2020?:
>
>use with Parent.Child;
>use limited private with Some_Other_Package;

The second makes no sense, since it is illegal to "use" the limited view of a
package.

Indeed, there are many things that cannot be "use"d:

    * limited views of packages
    * generic packages
    * subprograms
    * generic subprograms

That means that any such syntax cannot be used generally; a substantial part of
the language-defined units of Ada are not normal packages
(Ada.Unchecked_Conversion, Ada.Unchecked_Deallocation, Ada.Containers.Vectors,
Ada.Strings.Hash, Ada.Strings.Equal_Case_Insensitive, and dozens more).

...
>I don't like the old 2003 proposal of "with and use".  It sounds awkward and
>would be unsuitable for sorting.

This statement doesn't make any sense. No one is sorting Ada source code with a
program, and for manual sorting, one completely ignores the prefix and puts the
unit names in order.

After all, the critical information in a context clause is the list of units
that the current unit depends upon. Everything else is, at best, a convenience
feature. One must not let convenience get in the way of readability for the
critical information.

Any sane style for writing a context clause cannot obscure the list of units;
I've used a number of different styles over the years but the common thread is
that things other than "with"s (pragmas, use clauses) are hidden either on the
right or at the end. That's because for most uses, you never need to look at
those things; you're looking to seee if a particular unit is in the list or if
it needs to be added.

The language's syntax was designed to encourage such an organization, and
certainly the language requires all of the "with"s to come before the associated
"use". Any new syntax has to preserve this property.

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

Questions? Ask the ACAA Technical Agent