Version 1.1 of acs/ac-00078.txt

Unformatted version of acs/ac-00078.txt version 1.1
Other versions for file acs/ac-00078.txt

!standard 3.02.01(03)          03-09-07 AC95-00078/01
!class amendment 03-09-12
!status received no action 03-09-12
!status received 03-09-09
!subject Proposal for a "with and use" clause
!summary
!appendix

From: Gautier de Montmollin
Sent: Tuesday, September 9, 2003  1:11 PM

Proposal for a "with and use" clause

Hello!

Almost the only thing I find tedious in Ada is the obligation
to name twice packages you intend to _use_ in a context_clause.
I illustrate with examples two usual ways of organizing context clauses:

(A)

-- (1) With'ed only
with Ada.Command_Line;

-- (2) With'ed and Use'd
with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;

Problem: in practice the list pair (2) is a lot longer (many many lines) and
         becomes difficult to synchronize. It is also difficult then to
         _verify_ that the pair is consistent

(B)

-- (1) With'ed only
with Ada.Command_Line;

-- (2) With'ed and Use'd
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Integer_Text_IO;               use Ada.Integer_Text_IO;
with Ada.Float_Text_IO;                 use Ada.Float_Text_IO;

Advantage: much easier to verify and transport across sources
Problem: the beginning of sources becomes awfully long.

To sum up, I'd describe the current situation so

- beginner-repellent and newcomer-repellent (not to neglect !)
- ugly
- redundant
- causes a readability problem and possible confusions
- pushes the real thing, i.e. the programming contents after
  "procedure/package... is", too far away of the source's top
- needs too much administration

My proposal: a "with and use" clause. "with and use A[,B]" would
mean "with A[,B]; use A[,B]".

(C)

-- (1) With'ed only
with Ada.Command_Line;

-- (2) With'ed and Use'd
with and use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;

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

From: Mark Lundquist
Sent: Tuesday, September 9, 2003  1:23 PM

I think I floated something like this out a while back.  If not, I
meant to do so :-)

My only suggestion is a less heavyweight syntax.  "with and use" is too
COBOL-esque to my eye :-)  I'd prefer

	use with Ada.Text_IO;

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

From: Nick Roberts
Sent: Tuesday, September 9, 2003  5:37 PM

It's totally aesthetic, of course, but I rather like "with and use".

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

From: Gautier de Montmollin
Sent: Wednesday, September 10, 2003  4:15 AM

I prefer to put "with" before "use" since the package is "with"ed before
being "use"d.
Maybe "with, use Ada.Text_IO;" as an alternative ?

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

From: Jeffrey Carter
Sent: Wednesday, September 10, 2003  8:26 PM

If we're going to do something like, and I'm not convinced it's needed
or even desireable, then why not simply say that, in a context clause
and ONLY in a context clause, one can write

use X;

where X has not been mentioned before, and have it equivalent to

with X; use X;

?

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

From: Randy Brukardt
Sent: Tuesday, September 9, 2003  10:36 PM

> Problem: in practice the list pair (2) is a lot longer (many many
> lines) and
>          becomes difficult to synchronize. It is also difficult then to
>          _verify_ that the pair is consistent

This presumes that the with and use lists ought to be the same. But that is
almost never the case. Rarely used packages should never be "use"d, because
it adds confusion to the reader. Presuming the program has appropriate (low)
coupling, there shouldn't be many packages that need to be "use"d.

The rule of localization suggests that in many of the cases where use
clauses are needed, they should be placed in local scopes.

If Ada 200Y adopts the prefix call notation as an option, the main problem
with avoiding use clauses (the difficulty of figuring out the right place
for an inherited operation) will go away. So they will be even less
necessary than in Ada 95.

So this proposal seems to me to be mainly aimed at making a dubious style
easier. It's not clear why the language should do that (there are a lot of
styles that the language could make easier which seem better supported).

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

From: Gautier de Montmollin
Sent: Wednesday, September 10, 2003  12:18 PM

# This presumes that the with and use lists ought to be the same.

It doesn't presume it, hence the (1) and (2) lists...

# But that is almost never the case. Rarely used packages should never be "use"d, because
# it adds confusion to the reader. Presuming the program has appropriate (low)
# coupling, there shouldn't be many packages that need to be "use"d.

It depends. For instance you can have programs where *many* packages are
also *often* used !
A "small" example in my sources:
  GWindows, GWindows.Application, GWindows.Base, GWindows.Buttons,
  GWindows.Common_Dialogs, GWindows.Combo_Boxes, GWindows.Constants, GWindows.Cursors,
  GWindows.Drawing.Capabilities, GWindows.Drawing_Panels, GWindows.Edit_Boxes,
  GWindows.GStrings, GWindows.Image_Lists, GWindows.Menus,
  GWindows.Message_Boxes, GWindows.Static_Controls,
  GWindows.Windows, GWindows.Windows.MDI;
In comparison, there are only a couple of "GWindows.*" I prefer to only
"with".

# The rule of localization suggests that in many of the cases where use
# clauses are needed, they should be placed in local scopes.

It depends, too. For certain "technical" packages it is more secure and readable
to localize the "use" at most, but for a standard package likely to be broadly used
(e.g. Ada.Numerics.Long_Elementary_Functions) it would be just a silly noise in the
sources.

My proposal is for making everyday's programming a bit easier and actually cleaner.
I suspect that this small detail plays a non-negligible role in Ada's unpopularity.
Just for a small Pascal program with a few maths and I/O the Ada translation needs
all that

  with Ada.Text_IO;                       use Ada.Text_IO;
  with Ada.Integer_Text_IO;               use Ada.Integer_Text_IO;
  with Ada.Float_Text_IO;                 use Ada.Float_Text_IO;
  with Ada.Direct_IO;
  with Ada.Numerics;                      use Ada.Numerics;
  with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
  with Ada.Unchecked_Deallocation;

... before the program itself. Of course the reference to these packages themselves
is a good thing, but the double naming of 5 of the 7 packages is a useless redundance.

# If Ada 200Y adopts the prefix call notation as an option, the main problem
# with avoiding use clauses (the difficulty of figuring out the right place
# for an inherited operation) will go away. So they will be even less
# necessary than in Ada 95.

I am not fully "inside" the development - but would it solve the "problem" ?

# So this proposal seems to me to be mainly aimed at making a dubious style
# easier. It's not clear why the language should do that (there are a lot of
# styles that the language could make easier which seem better supported).

My point of view: the use_clause as a context_clause is there, it is
useful ( :-) ). It forces package names to be written twice, and _that_ is a
dubious (forced) style.

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

From: Randy Brukardt
Sent: Wednesday, September 10, 2003  8:09 PM

> # This presumes that the with and use lists ought to be the same.
>
> It doesn't presume it, hence the (1) and (2) lists...

My point is that (2) should almost never happen.

> # But that is almost never the case. Rarely used packages should never be "use"d, because
> # it adds confusion to the reader. Presuming the program has appropriate (low)
> # coupling, there shouldn't be many packages that need to be "use"d.
>
> It depends. For instance you can have programs where *many* packages are
> also *often* used !
> A "small" example in my sources:
>   GWindows, GWindows.Application, GWindows.Base, GWindows.Buttons,
>   GWindows.Common_Dialogs, GWindows.Combo_Boxes, GWindows.Constants,
>   GWindows.Cursors, GWindows.Drawing.Capabilities, GWindows.Drawing_Panels,
>   GWindows.Edit_Boxes, GWindows.GStrings, GWindows.Image_Lists, GWindows.Menus,
>   GWindows.Message_Boxes, GWindows.Static_Controls,
>   GWindows.Windows, GWindows.Windows.MDI;
> In comparison, there are only a couple of "GWindows.*" I prefer to only
> "with".

Yikes! You obviously should have used Claw, which was designed to be used
without use clauses. :-)

But seriously, there is a problem with OOP designs in that figuring out
where routines are declared is hard. So people toss in dozens of use clauses
in order to avoid needing to do that (which would be needed for
fully-qualified calls). I agree that there is a language problem in that
case, but the solution isn't to make more forms of use clause! The prefix
call notation would avoid the need for the use clauses in the first place:

     My_Window.Show;

does not need a package name nor a use clause.

> # The rule of localization suggests that in many of the cases where use
> # clauses are needed, they should be placed in local scopes.
>
> It depends, too. For certain "technical" packages it is more secure and readable
> to localize the "use" at most, but for a standard package likely to be broadly used
> (e.g. Ada.Numerics.Long_Elementary_Functions) it would be just a silly noise
> in the sources.

It's rare that a standard package is heavily used enough to justify the use
of a use clause.

> My proposal is for making everyday's programming a bit easier and actually
> cleaner. I suspect that this small detail plays a non-negligible role in Ada's
> unpopularity. Just for a small Pascal program with a few maths and I/O the Ada
> translation needs all that
>
>   with Ada.Text_IO;                       use Ada.Text_IO;
>   with Ada.Integer_Text_IO;               use Ada.Integer_Text_IO;
>   with Ada.Float_Text_IO;                 use Ada.Float_Text_IO;
>   with Ada.Direct_IO;
>   with Ada.Numerics;                      use Ada.Numerics;
>   with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
>   with Ada.Unchecked_Deallocation;
>
> ... before the program itself. Of course the reference to these packages
> themselves is a good thing, but the double naming of 5 of the 7 packages is a useless
> redundance.

Yikes again! This is precisely the sort of thing that should not happen for
a number of reasons. Personally, I almost never "use" Ada.Text_IO; it's
short enough to write out. Similarly, I never use the shortcut packages like
Ada.Integer_Text_IO, because an instantiation provides both a shorter name
and the ability to avoid system-defined types. I wouldn't "use" Ada.Numerics
either, because there is almost nothing in it, and I wouldn't even want a
very short name like 'e' or 'pi' to be unqualified -- there would be no hope
of figuring out where it came from (you can't search on it, that's for sure).
Thus, this header would have no use clauses at all if I wrote it (there
probably would be a use clause following the instantiation of
Generic_Elementary_Functions, but of course that cannot be in the header).

...
> # So this proposal seems to me to be mainly aimed at making a dubious style
> # easier. It's not clear why the language should do that (there are a lot of
> # styles that the language could make easier which seem better supported).
>
> My point of view: the use_clause as a context_clause is there, it is
> useful ( :-) ). It forces package names to be written twice, and _that_ is a
> dubious (forced) style.

Well, I agree that it is there. But I think the duplicated names is a good
thing, because it encourages users to avoid the clause in the first place --
which is certainly a good thing.

In any case, even if you like use clauses, you have to admit that this is
WAAAYY down on the priority list. This is not a case where something is hard
or impossible to do in the current language. So virtually every other
proposal (with the possible exception of the one changing the title of Annex
H) is more valuable. And this would be reasonably expensive to implement, as
it would require changes in not only the syntax but also the data structures
used for processing context clauses. As well as changes to the make tool. So
this is neither real cheap (like changing the title of Annex H) nor real
important -- which means it probably doesn't make the cut. Ada 9x, after
all, had a number of good ideas that were left out of the final language
simply because they were not important enough. The same will be true with
Ada 200Y.

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

From: Gautier de Montmollin
Sent: Saturday, September 13, 2003  4:09 PM

[lots of GWindows.*]

Randy:

#  Yikes! You obviously should have used Claw, which was designed to be used
#  without use clauses. :-)

Oh, so next time should I use Claw then ?...
Mmmh I would be able to make a large use of the use_clause there too
(for Claw.Radio_button, Claw.Push_button, ...).

#  But seriously, there is a problem with OOP designs in that figuring out
#  where routines are declared is hard. So people toss in dozens of use clauses
#  in order to avoid needing to do that (which would be needed for
#  fully-qualified calls). I agree that there is a language problem in that
#  case, but the solution isn't to make more forms of use clause! The prefix
#  call notation would avoid the need for the use clauses in the first place:
#
#       My_Window.Show;
#
#  does not need a package name nor a use clause.

You have this point! - and the prefixed notation would be nice.

[Ada.Numerics.Long_Elementary_Functions etc.]

#  It's rare that a standard package is heavily used enough to justify the use
#  of a use clause.

Our statistics differ, Sir !

#  >   with Ada.Text_IO;                       use Ada.Text_IO;
#  >   with Ada.Integer_Text_IO;               use Ada.Integer_Text_IO;
#  >   with Ada.Float_Text_IO;                 use Ada.Float_Text_IO;
#  >   with Ada.Direct_IO;
#  >   with Ada.Numerics;                      use Ada.Numerics;
#  >   with Ada.Numerics.Elementary_Functions; use
#  Ada.Numerics.Elementary_Functions;
#  >   with Ada.Unchecked_Deallocation;
...
#  Yikes again! This is precisely the sort of thing that should not happen for
#  a number of reasons. Personally, I almost never "use" Ada.Text_IO; it's
#  short enough to write out.

Unfortunately I have a keyboard whithout programmable extra keys to write
"Ada.Text_IO." at all places I need to write "Put". And even then I would
hate polluting my sources with parasite verbosity...

[...]
#  In any case, even if you like use clauses, you have to admit that this is
#  WAAAYY down on the priority list.

Indeed I hope there are more important things to be implemented :-) .

#  This is not a case where something is hard
#  or impossible to do in the current language. So virtually every other
#  proposal (with the possible exception of the one changing the title of Annex
#  H) is more valuable. And this would be reasonably expensive to implement, as
#  it would require changes in not only the syntax but also the data structures
#  used for processing context clauses.

Are you so sure ? It relies only on what the compiler does for a
with_clause and a use_clause. It should be trivial to implement - after all
"with and use A[,B]" = "with A[,B]; use A[,B]".

#  As well as changes to the make tool. So
#  this is neither real cheap (like changing the title of Annex H) nor real
#  important -- which means it probably doesn't make the cut. Ada 9x, after
#  all, had a number of good ideas that were left out of the final language
#  simply because they were not important enough. The same will be true with
#  Ada 200Y.

My theory is that advanced features should of course have the priority, but
a small basic thing like that should not be neglected in terms of pushing
Ada a bit towards a growing orbital.

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

From: Pascal Leroy
Sent: Monday, September 15, 2003  1:36 AM

> Are you so sure ? It relies only on what the compiler does for a
> with_clause and a use_clause. It should be trivial to implement - after all
> "with and use A[,B]" = "with A[,B]; use A[,B]".

Never say "trivial" when it comes to Ada.  Equivalence rules never work.
Examples of issues that would crop up with this proposal include:

1 - "with A.B" does an implicit "with A".  "use A.B" doesn't do an
implicit "use A".  What should the rule be for "with and use"?

2 - There are also interactions with "private with" (AI 262) and
"limited with" (AI 217).  Should "private with and use A" be illegal?
Or should it cause the use clause to take effect at the beginning of the
private part?  This reeks of Beaujolais effects...

I am not saying that these questions cannot be answered satisfactorily,
and perhaps they are no big deal, but they need to be studied.  The RM
cannot define a construct of the language by saying "you know,
with-and-use, it does a with and a use..."

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

From: Gautier de Montmollin
Sent: Tuesday, September 16, 2003  12:22 PM

# Never say "trivial" when it comes to Ada.

Sorry for the coarse word. I won't say it again. Promised. I'm sorry.

# Equivalence rules never work.
# Examples of issues that would crop up with this proposal include:
#
# 1 - "with A.B" does an implicit "with A".  "use A.B" doesn't do an
# implicit "use A".  What should the rule be for "with and use"?

Exactly the rule that applies for "with A.B; use A.B;": A.B and A are
"with"ed, A.B only is "use"d here. As I see it, the above equivalence is
really textual (a sort of meta-equivalence), all rules would follow
(better so) exactly _as if_ the "with *; use *;" were written.

# 2 - There are also interactions with "private with" (AI 262) and
# "limited with" (AI 217).  Should "private with and use A" be illegal?
# Or should it cause the use clause to take effect at the beginning of the
# private part?  This reeks of Beaujolais effects...

Clearly I would specify a "with and use" only. No "private with and use"
or whatever. On there other hand it could be interesting to have
another bottle to win...

# I am not saying that these questions cannot be answered satisfactorily,
# and perhaps they are no big deal, but they need to be studied.  The RM
# cannot define a construct of the language by saying "you know,
# with-and-use, it does a with and a use..."

I'm pretty confident that this issue will be discussed enough,
and I'm sure that even if we tried to write such a phrasing into the RM
it would erase it itself or at least try to raise an exception in the
printing machine.

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

From: Gautier de Montmollin
Sent: Wednesday, September 17, 2003  11:27 PM

Jeffrey Carter:

# If we're going to do something like, and I'm not convinced it's needed or
# even desireable, then why not simply say that, in a context clause and
# ONLY in a context clause, one can write

# use X;

# where X has not been mentioned before, and have it equivalent to

# with X; use X;

# ?

This is a good idea. One has to verify that the "use X" without "with X"
cannot refer accidentally to another previously visible "X".
It might also change a bit how "use" has to search entities.
I'd say: better idea, possible "Beaujolais" 's to chase (contrary to "with
and use").

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


Questions? Ask the ACAA Technical Agent