Version 1.1 of acs/ac-00137.txt

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

!standard 12.3          06-11-13 AC95-00137/01
!class Amendment 06-11-13
!status received no action 06-11-13
!status received 06-11-03
!subject
!summary
!appendix

[Editor's note: This appeared as an aside in an unrelated discussion;
only the mail on the aside is filed here. The rest is filed in
AI05-0025-1.TXT.]

From: Adam Beneschan
Date: Friday, November  3, 2006  6:00 PM

(P.S. I'll reiterate something I said on comp.lang.ada: it might be
helpful to have a way in such cases to allow programmers to use the <>
syntax of formal subprograms but allow the name to be different from
the name of the formal subprogram, something like this:)

    generic
        type T1 is private;
        type T2 is private;
        with function T1_Equal (Left, Right : T1) return Boolean is <> ("=");
        with function T2_Equal (Left, Right : T2) return Boolean is <> ("=");
    package GP1 is ...

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

From: Randy Brukardt
Date: Friday, November  3, 2006  10:21 PM

But this solves the wrong problem; we really want the names of the functions
inside the generic to be overloaded and "=". I don't want to have to write
"if T1_Equal (A, B) then" because that requires figuring out the type name
(often the thing I find hardest to remember; usually I know the objects, but
not [exactly] the types).

Moreover, the above could cause subtle bugs: if I write "if A = B then" I'll
get the original "=", not the one passed in. Which will work fine until
someone tries to use a custom "=". Yuck.

The problem here is that we don't handle overloading of parameter names, so
what we need is a way to rename the parameter names for the formals. One
option would be something like:

     generic
         type T1 is private;
         type T2 is private;
         with function "=" (Left, Right : T1) return Boolean
            is <> named T1_Equal;
         with function "=" (Left, Right : T2) return Boolean
            is <> named T2_Equal;
     package GP1 is ...

and in this case, you'd be required to use the name in the "named" clause as
the parameter name in instantiations and formal packages. That is, your
example above would become:

         with package The_Pak1 is new GP1
              (T1 => T1, T2 => T2, T1_Equal => <>, T2_Equal => <>);

which is not a problem. Use of "=" => <> would be illegal, even if not
overloaded.
(Of course, in this particular example, it probably would have been better
to say:
         with package The_Pak1 is new GP1
              (T1 => T1, T2 => T2, others => <>);
which requires no new language, but that doesn't hold for instantiations.)

Still, this seems to be a minor problem.

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

From: Adam Beneschan
Date: Monday, November  6, 2006  10:21 AM

> But this solves the wrong problem; we really want the names of the functions
> inside the generic to be overloaded and "=".

I figured you could use a rename inside the generic declaration to get
around that:

    function "=" (Left, Right : T1) return Boolean renames T1_Equal;

Maybe it won't work for some reason that I haven't thought of.  But
doing it the other way, as per your suggestion

>      generic
>          type T1 is private;
>          type T2 is private;
>          with function "=" (Left, Right : T1) return Boolean
>             is <> named T1_Equal;
>          with function "=" (Left, Right : T2) return Boolean
>             is <> named T2_Equal;
>      package GP1 is ...

would be OK also.  The biggest problem I can think of there is that if
you want to use named association in an instantiation, and you're
looking at the generic declaration to figure out what the names of the
formals are, this may make it a bit harder since the name would be in
an unusual place (i.e. this would be the only case where the name is
not the first non-keyword in a generic_formal_parameter_declaration).
But perhaps that's a minor point.  I agree that the issue is probably
a minor one anyway, although it did come up based on an actual example
that someone on c.l.a was trying to write.

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

From: Robert A. Duff
Date: Monday, November  6, 2006  2:44 PM

>...  I agree that the issue is probably
> a minor one anyway, although it did come up based on an actual example
> that someone on c.l.a was trying to write.

I've run into this issue myself.  But I think it's not sufficiently broken to
be worth fixing.

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

From: Tucker Taft
Date: Monday, November  6, 2006  5:19 PM

I would rather directly solve the problem of being unable to use
named notation when there is overloading.  We could adopt a syntax
analogous to that used for referring to different dimensions of an
array, e.g:

     "="(1) => Foobar, "="(2) => Fum

Not pretty, but it seems pretty clear what it means.

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

From: Pascal Leroy
Date: Tuesday, November  7, 2006  3:04 AM

Well, this is hardly better than positional notation, in the sense that if
the order of the formal parameters changes in the generic surprising
things can happen.

I am not really annoyed by the fact that you cannot give named
associations for overloaded formal subprograms.  What I find obnoxious is
that, because formal subprograms tend to occur late in the list of formal
parameters, this forces many other parameters to use positional notation,
even though they don't involve overloading.  We could alleviate this
problem without inventing weird new syntax by simply relaxing a bit the
positional-before-named rule in this case.

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

From: Robert A. Duff
Date: Tuesday, November  7, 2006  5:18 PM

>...We could alleviate this
> problem without inventing weird new syntax by simply relaxing a bit the
> positional-before-named rule in this case.

The "positional-before-named rule" was a bad idea from the start.
But how can we relax it now, without compatibility concerns?

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

From: Simon Wright
Date: Tuesday, November  7, 2006  5:34 PM

Would using generic signature packages have got round the original
problem?

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

From: Randy Brukardt
Date: Tuesday, November  7, 2006  6:00 PM

Not sure which problem you are referring to.

The original bug that Adam reported is in the definition of generic formal
packages. Splitting the package into two would eliminate the concern, but
that's irrelevant, since the rules would still be wrong and need fixing.

The off-topic aside has an example with two "=" operators. I suppose
spliting that formal package into two would work in that case, but it's not
a general solution, and it would add complexity (using two formal packages
instead of one). (To see why it is not general, imagine a package with
multiple mixed "+" operators, or multiple Put routines, or any other
overloading on a single type.)

The generalization of the off-topic aside might benefit from using a formal
package instead, but again you are adding complexity. I don't think a
signature package is a good solution when all you are talking about are
predefined operators; it makes more sense with a more complex set of
operations. (And one wonders whether an interface isn't a better solution
then, but I digress.)

So I think the answer is no - it might help in some specific example, but is
not general in any way.

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

From: Adam Beneschan
Date: Tuesday, November  7, 2006  6:03 PM

> Would using generic signature packages have got round the original
> problem?

I assume that by "original problem" you mean the second one I briefly
alluded to my first message---not the missing rule that's the subject
of the thread.  (The "missing rule" problem isn't something that needs
to be gotten around.)

The situation was something like this:

    generic
        type T1 is private;
        type T2 is private;
        with function "=" (Left, Right : T1) return Boolean is <>;
        with function "=" (Left, Right : T2) return Boolean is <>;
    package GP1 is
        ...
    end GP1;

The main problem, as I see it: If, when instantiating, you want to use
something other than the default for one or both of the "="
subprograms, then you can't use named notation when you instantiate
(even for the T1 and T2 formals)---you have to use positional
notation.  And Ada doesn't give you a way to allow named notation by
naming the formal "=" subprograms something else.  But you can still
do the instantiation; I don't think this problem causes a situation
where you can't do something you need to do.  You can do what you
need, you just can't do it in the most readable way.  (And you can add
comment(s) near the instantiation to help explain things, if needed.)
That's probably why Randy referred to this as a minor problem.

Generic signatures thus aren't needed to get around any problem, and I
don't think they'd enhance readability at all.  IMHO they'd just add
needless clutter.

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

From: Pascal Leroy
Date: Wednesday, November  8, 2006  2:39 AM

> The "positional-before-named rule" was a bad idea from the
> start. But how can we relax it now, without compatibility concerns?

If we were to relax this rule (and I am only talking about generic
instantiations with overloaded formal parameters) then you could write
something like:

	T => Integer, C => 42, "+", "+"

and this would not create any incompatibility because such an ordering is
currently always illegal.  Of course, the rules would have to be crafted
carefully so that we do not lose coverage checking and all these good
things.

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

From: Adam Beneschan
Date: Wednesday, November  8, 2006  12:10 PM

> I am not really annoyed by the fact that you cannot give named
> associations for overloaded formal subprograms.  What I find obnoxious is
> that, because formal subprograms tend to occur late in the list of formal
> parameters, this forces many other parameters to use positional notation,
> even though they don't involve overloading.  We could alleviate this
> problem without inventing weird new syntax by simply relaxing a bit the
> positional-before-named rule in this case.

Another possibility would be to keep the positional-before-named rule,
but relax 12.3(9) to allow named associations where multiple formal
subprograms have the same name.  The first such named association in
the instantiation would be for the first formal with that name, the
second (if any) would apply to the second formal with that name, etc.
I'd want a rule that you could not use both a positional association
and a named association in the same instantiation to apply to formal
subprograms with the same name, to avoid some really confusing
possibilities.

Like Pascal's suggestion, this has the advantage of not requiring any
new syntax.  A disadvantage of both approaches is that if you have two
"=" formal subprograms, you can't let the first one default and
specify an actual parameter for the second, although it's easy to
enough to write "=" => "=" for the first so this probably isn't a big
disadvantage.

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

From: Tucker Taft
Date: Wednesday, November  8, 2006  12:21 PM

I think I marginally prefer Adam's suggestion,
namely that you can give the same name twice
if the generic formal is overloaded.  I would go
further and require that if you use a named
parameter for an overloaded name, then you must
give one for *each* overloading of the name, to make it crystal
clear that you are aware that the name is overloaded,
and you are specifying what you want for each one.
Yes this defeats using defaults, but the potential
for error seems just too high if you are allowed
to specify just one of two overloaded parameters,
since you might just not have noticed that there was an
earlier parameter with the same name.

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

From: Robert A. Duff
Date: Wednesday, November  8, 2006  3:03 PM

I agree with all of the above, assuming we really want to fix this problem at
all.  I still say, "insufficiently broken".

By the way, here's a workaround: declare two generic packages.  One uses names
like This_Equal and That_Equal.  The other uses "=" and "is <>".  One
instantiates the other.  If you want to use named notation, instaniate the
former.  If you want to take advantage of "is <>", instantiate the latter.

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

From: Jean-Pierre Rosen
Date: Thursday, November  9, 2006  12:56 AM

> Like Pascal's suggestion, this has the advantage of not requiring any
> new syntax.  A disadvantage of both approaches is that if you have two
> "=" formal subprograms, you can't let the first one default and
> specify an actual parameter for the second, although it's easy to
> enough to write "=" => "=" for the first so this probably isn't a big
> disadvantage.

I agree with that, but you need to allow "=" => <> for defaulted value.
The default may not be visible at the place of the instantiation, so you
really need a way to specify that you want the default.

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

From: Adam Beneschan
Date: Thursday, November  9, 2006  10:17 AM

Maybe.  But the whole idea was that the problem only occurs when the
*generic* *formal* is specified with a <> default:

   generic
       type T1 is private;
       type T2 is private;
       function "=" (Left, Right : T1) return Boolean is <>;
       function "=" (Left, Right : T2) return Boolean is <>;
   package ...

and if I understand the rules correctly, "=" => "=" is always
equivalent to not specifying an explicit actual (12.6(10)).  This case
is a problem because the Ada syntax doesn't give you a way to specify
the generic formal subprograms with unique names.  In the case I think
you're thinking of, where the *generic* *formal* has an explicit
default:

   generic
       ...
       with procedure Output (X : String) is Text_IO.Put_Line;


there's no issue because you can always give the generic formal
subprograms unique names.  I suppose it could become an issue if
someone really, really, really wants to overload a generic formal
subprogram name when they don't need to:


   generic
       ...
       with procedure Output (X : String) is Text_IO.Put;
       with procedure Output (X : Character) is Text_IO.Put;

but I don't see why anybody would want to.

Still, since Ada 200Y allows => <> in aggregates, it wouldn't be too
much of a stretch to allow it in instantiations also, although I don't
think it's necessary.

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


Questions? Ask the ACAA Technical Agent