Version 1.6 of ai05s/ai05-0187-1.txt

Unformatted version of ai05s/ai05-0187-1.txt version 1.6
Other versions for file ai05s/ai05-0187-1.txt

!standard 5.2.1 (0)          09-11-03 AI05-0187-1/01
!class amendment 09-11-03
!status No Action (8-0-2) 10-02-27
!status work item 09-11-03
!status received 09-11-02
!priority Low
!difficulty Medium
!subject Shorthand for assignments with expressions naming target
!summary
A syntactic shorthand is introduced for assignment statements with expressions that include references to the target object.
!problem
It would be useful to have a shorthand for an assignment that updates its target object with an expression involving the target.
That is, for common assignments of a form such as:
<target-object> := <target-object> <some-operator> <some-value>;
or even more generally of the form:
<target-object> := <some expression which references target-object>;
the objective is to be able to write this without repeating the name of the target object.
The motivation here would be to aid readability, because often such assignments involve an object with a longish identifier (as Ada tends to encourage) or a complex compound name, and repeating the full name in the assignment expression is unwieldy and tends to make the statement too heavy and hence less readable.
!proposal
C and C++ allow shorthand forms for assignment such as "SomeObject += 1", and the proposal is to add a similar capability in Ada. This could be done using the same kind of syntactic notation as C (e.g., A +:= B), that would allow cases involving binary operators, or using a more general approach that would work for other forms of expression, by adding a new form of primary that would stand for the left-hand side. The latter alternative would permit arbitrary use of the target object's name on the assignment's right-hand side (e.g., Target_Object := Func (T_O)).
(Note: There are some ARG members who prefer the first approach, and others who prefer the second, so further discussion is needed before writing up any details.)
!wording
** TBD **
!discussion
** TBD **
!examples
** TBD **
!ACATS test
ACATS C-Tests are needed to check this feature.
!appendix

From: Gary Dimukes
Sent: Monday, November 2, 2009  12:57 PM

While we're on the subject of minor proposals to consider for the next revision,
and since this is the last opportunity to put them on the table, there's one
that I'd like to float that pops up in my mind from time to time.

It would be nice to have a shorthand for making an assignment that updates its
target object using an expression that involves the target.

That is, for common assignments of a form such as:

    <target-object> := <target-object> <some-op> <some-value>;

to be able to write this without repeating the name of the target object.

The motivation here would be to aid readability, because often such assignments
involve an object with a longish identifier (as Ada tends to encourage) or a
complex compound name, and repeating the full name in the assignment expression
is unwieldy and tends to make the statement too heavy and hence less readable.

C and C++ allow shorthand forms for assignment such as "SomeObject += 1", and
I'm proposing to allow something similar, but more general, for Ada. Rather than
extending the syntax for the assignment token, I would add a new form of primary
that would stand for the left-hand side.  This would permit arbitrary use of the
target object's name on the right-hand side (e.g., Target_Object := Func (T_O).

If such a feature were to be added, the tricky part is to come up with a
reasonable syntax for denoting the object.  Adding a new reserved word
presumablby won't fly (and there aren't any suitable existing reserved words),
and using an identifier for this would be a bad idea in any case.  Some short
but reasonably distinctive and obtrusive token is what's needed.  One fairly
obvious choice would be Ada's existing <> token.  That won't work though,
because it clashes with Ada 05's addition of box defaults in aggregates (unless
we were to syntactically restrict the new token's use, though I wouldn't
recommend that).  In the absence of any obvious existing token, and for purposes
of discussion (if there's any interest in such), I'll suggest a new compound
delimiter <<>> as a strawman, formed by sticking the existing left and right
label brackets together.  (Another choice could be '$', but that might be
considered too U.S.-centric;-)

The only other issue I see is to define the semantics of evaluating the symbol
denoting the target object.  It could be defined as a textual macro, so each
occurrence of the name would be reevaluated, but I believe the more appropriate
semantics would be to bind the name once, when the left-hand side name is
evaluated, making it equivalent to a renaming.  So each occurrence in the
assignment expression denotes the value of the single object determined by the
target name.  (This means requiring evaluation of the target object before the
expression, but that seems fine.)

Is there any interest in considering this proposal?  If so, I can take care of
drafting the AI.

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

From: Tucker Taft
Sent: Monday, November 2, 2009  1:16 PM

I'd be more interested in just allowing the "<operator>=" syntax:

   X <operator>= Y;

would be equivalent to

   X := X <operator> Y;

except of course "equivalent" is never really just "equivalent" ;-).

Inventing some other syntax to mean the LHS is just making Ada harder to read
for non-Ada folks, while adding "<operator>=" would make it easier for non-Ada
folks to learn to read (and write) Ada.

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

From: Randy Brukardt
Sent: Monday, November 2, 2009  1:29 PM

> Is there any interest in considering this proposal?  If so, I can take
> care of drafting the AI.

I'm mildly interested in this idea.

I'm not at all interested in Tucker's suggestion of copying C++, because I find
that it is quite common to need this in function calls:

     Target := Func(Target, ...);

Given Ada's equivalence of operators to functions, you sould have to be able to
handle user-defined operators in a :=+ operator anyway. Moreover, the resolution
would be messy (you'd have to handle operators where the Right operand is a
different type). And that would give an unnatural incentive to name functions as
operators if they commonly occurred in this form -- that seems exactly wrong.

(We'd also need to add three character or more delimiters, something Ada does
not already have. I don't know if adding new delimiters is actually a problem,
but it surely would add to the costs of a new feature.)

If Ada can do something *better* that existing languages, we at least ought to
consider that. Blindly copying other ideas does little to enhance the case for
using Ada.

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

From: Steve Baird
Sent: Monday, November 2, 2009  5:59 PM

> I'd be more interested in just allowing the "<operator>=" syntax:
...

If we want to go with this approach, as
opposed to the more general approach that Gary and Randy were discussing, I
think a better way to define the semantics of
    <lhs> <operator>= <opnd2>;
via an equivalence is in terms of an implicit rename declaration, as in
    declare
       <anonymous> : <lhs>'Type renames <lhs>;
    begin
       <anonymous> := <anonymous> operator <opnd2>;
    end;

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

From: Robert Dewar
Sent: Monday, November 2, 2009  11:11 PM

> I'd be more interested in just allowing the "<operator>=" syntax:
...

I agree that a simple form is better, though I think the
A68 syntax is a better choice for Ada

     X +:= 1;

I like the assignment symbol appearing, and in fact this is a better analog of
the C practice than

    X += 1;

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

From: Robert Dewar
Sent: Monday, November 2, 2009  11:12 PM

> I'm not at all interested in Tucker's suggestion of copying C++,
> because I find that it is quite common to need this in function calls:
>
>      Target := Func(Target, ...);

Yes, but I still find the proposal unwieldy and ugly, and I think I prefer to
see things spelled out in a case like this.

> If Ada can do something *better* that existing languages, we at least
> ought to consider that. Blindly copying other ideas does little to
> enhance the case for using Ada.

I don't think this fancy proposal *is* better, I think it is too obscure.

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

From: Tucker Taft
Sent: Monday, November 2, 2009  11:37 PM

I guess I just find "+:=" uglier than "+=".
Also, Algol 68 had to distinguish "+:=" from "+=:"
and I don't think we have that issue in Ada (though I don't know what "+=:"
meant!).

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  6:43 AM

Nor me, totally unfamiliar, are you sure this was in Algol68

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

From: Tucker Taft
Sent: Tuesday, November 3, 2009  7:37 AM

Here is a hand-drawn Algol 68 syntax chart from an old ACM Communications.  It
shows both "<op>:=" and "<op>=:" (I think!):

    http://www.sofport.com:5055/ARG/algol-68-p39-peck.pdf

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  10:53 AM

Well the date suggests it may be preliminary, and I sure don't remember the
other form, what would it mean? I may just have forgotten of course

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  11:10 AM

Anyway, never mind what A68 had, I
prefer +:= because it makes it clear
it is still an assignment, just as
in C += is still clearly an assignment.

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

From: Gary Dismukes
Sent: Tuesday, November 3, 2009  12:20 PM

Looking at an Algol 68 textbook I have, it appears that the notation is only
available for use as an alternative to +:= for character strings.  It's called
the "plusto" operator, and "h +=: r" is equivalent to "r +:= h", where r is of
mode "ref string" and h is of mode string or char.

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

From: Brad Moore
Sent: Tuesday, November 3, 2009  12:30 PM

This is somewhat related to assignment shorthand, along the lines of improved
notation possibilities... (I apologize if this is too far off topic, if there is
any interest we can create a separate thread)

It would be nice if we could optionally use infix notation more generally for
boolean binary functions, instead of just operators.

e.g. Instead of

if Contains (Grocery_List, Radishes)
if Less_Than (X, Y)
if Is_Factor (3, 21) ... -- Is what a factor of what?

Being able to write

if Grocery_List Contains Radishes
if X Is_Less_Than Y
if 3 Factors_Into 21

Seems more natural.

We do have a reasonable approximation with object prefix notation,
but that only works for tagged types.
eg.
if Grocery_List.Contains(Radishes)

But if one doesn't have a tagged type, you are stuck with prefix notation,
unless you can overload an operator.

Would there be any interest in this capability?

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  12:57 PM

> Being able to write
>
> if Grocery_List Contains Radishes
> if X Is_Less_Than Y
> if 3 Factors_Into 21

This really should be a completely separate topic, it has nothing to do with an
assignment short hand.

Personally I don't like it, and it has huge implementation consequences (it
breaks the invariant that two identifiers cannot appear in sequence).

...
> Would there be any interest in this capability?

It's an interesting language capability (have a look at ABC for a fully
developed version), but to me it does not fit well with Ada syntax.

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

From: Brad Moore
Sent: Tuesday, November 3, 2009  2:09 PM

OK, but maybe this does tie in with assignment short hand afterall.
Suppose we said that an infix call had to be enclosed by <>.

As in,

  if 3 <Factors_Into> 21

This would address your concern about two identifiers appearing in sequence, and
would help make it clearer that an infix notation is being used.

Now suppose we extend this idea to also apply to binary procedure calls, in
particular where the first formal is an in out parameter.

Now suppose we added some predefined procedures for elementary types, eg.

procedure "+" (Sum : in out Integer; Addend : Integer);

Then we might be able to write using infix notation;

X <+> 3;  -- Equivalent to "+"(X, 3) or X := X + 3; or in C, X += 3;

This gives us a shorthand notation and gets around having to worry about the
assignment operator, because it is not an assignment. It is a procedure call.

I realize these ideas are a bit "out there", but maybe they will lead to
something...

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

From: Bob Duff
Sent: Tuesday, November 3, 2009  3:41 PM

...
> Would there be any interest in this capability?

I might consider something like that in a from-scratch language design, but I
don't think it's appropriate at this point in the life of Ada to be adding such
bells and whistles.

> As in,
>
>   if 3 <Factors_Into> 21

I don't think that works.  It would cause trouble for parsers, since "3
<Factors_Into" is a legal expression.

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

From: Bob Duff
Sent: Tuesday, November 3, 2009  3:53 PM

> I'll suggest a new
> compound delimiter <<>> as a strawman, formed by sticking the existing
> left and right label brackets together.

> Is there any interest in considering this proposal?  If so, I can take
> care of drafting the AI.

Like Randy, I have mild interest.  It seems trivial to implement, and somewhat
useful.

I think the "right" way to do it is to have a reserved word (perhaps "idem").
But we certainly don't want to tolerate upward compatibilities for this little
feature, so I agree with your choice of <<>>.

I don't like the += or +:= ideas, because they only work for operators.
The problem we're trying to solve is having to repeat the left-hand side of an
assignment on the right-hand side, which cause trouble because you have to
carefully compare the two, and because you have to worry about side effects.
Both of these:

    Table_Of_Gizmos(Current_Gizmo_Index).Blah_Blah := <<>> + 1;
    Table_Of_Gizmos(Current_Gizmo_Index).Line := Next_Link (<<>>);

seem equally useful.

<<>> should not reevaluate -- the side effects of the lhs should happen once.

I see Tucker's point that the += syntax is familiar to programmers of the C
family of languages.  Good point, but I still don't like it.  Anyway, for Ada to
be readable, you have to learn the language.  E.g.

    select
        ...
        or
            terminate;

Sure, "terminate" is a nice English word, but you can't really understand it
without learning what it means in Ada.

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

From: Gary Dismukes
Sent: Tuesday, November 3, 2009  3:31 PM

Here's a skeleton AI for the assignment shorthand proposal, in case it's
possible to add this to the agenda for the upcoming ARG meeting.  Since there
are two suggested approaches for such a feature, further discussion is needed,
so I've mentioned both and not pursued writing up a detailed proposal.

[Editor's note: this is version /01 of the AI.]

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

From: Edmond Schonberg
Sent: Tuesday, November 3, 2009  3:42 PM

> r using a more general
> approach that would work for other forms of expression, by adding a
> new form of primary that would stand for the left-hand side.  The
> latter alternative would permit arbitrary use of the target object's
> name on the assignment's right-hand side (e.g., Target_Object := Func
> (T_O)).

Maybe the digraph <- could be used for this purpose:

A.B := F (<-,  <-);

A (X) := <- + 1;

intuitively it hints at its purpose by pointing to the left-hand side in the
assignment.

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

From: Stephen Michell
Sent: Tuesday, November 3, 2009  6:23 PM

But I would say the same about +=, not worth the change to Ada.

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  7:34 PM

Well I must say that

    X (A, B, G + 1) := X (A, B, G + 1) + 1;

is pretty ugly, and the Ada way of getting around this is awfully heavy
(declare block, now if we could just say in functional style something like

    J := J + 1 where J = X (A, B, G + 1)

that would be better (please don't think of this as a language suggestion :-))

So to me

   X (A, B, G + 1) +:= 1;

is worthwhile, and trivial to learn, use and implement.

I am dubious about the more general forms with <<>> or whatever ...

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

From: Bob Duff
Sent: Tuesday, November 3, 2009  7:48 PM

I'm primarily concerned with implementation difficulty at this point.
Implementers are having trouble keeping up.  Up to Ada 2005, even, and
now we're talking about Ada 2012 or 2015 or whatever it's called.

The "+=" thing is trivial to implement, as is the <<>> thing, whereas
"if Grocery_List Contains Radishes" is probably not.

But having said that, I could easily be convinced that none of this is
worth the trouble!

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

From: Bob Duff
Sent: Tuesday, November 3, 2009  7:54 PM

> Maybe the digraph <- could be used for this purpose:

I like it!

In a from-scratch language design, I'd prefer a keyword.
How about the pronoun "it", as in "X[f(i)].Y := it + 1;"?
But as I said, I'm opposed to new reserved words for this purpose.

I can tolerate new reserved words, but only for something important.

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

From: Robert Dewar
Sent: Tuesday, November 3, 2009  8:06 PM

I still find this klunky compared to

     X[f(i)].Y +:= 1;

To me this notation takes care of the most common cases.

Note by the way that the example

     BLABLA := Next (BLABLA);

is more easily handled (as in the GNAT sources), by just introducing an
abstraction:

     Next (BLABLA);

which reads just fine, and indeed reads better than

     BLABLA := Next (<-);

or

     BLABLA := Next (it);

Whereas in the +:= case we are
comparing

     A +:= N;

with

     Increment (A, N);   (if we use procedural abstraction)

or

     A := <- + N;        (if we introduce a general
     A := it + N;           language gizmo)

and the +:= notation is better

After all the whole business of infix operators is redundant, we can
write:

    "+" (1, 2);

but we know that we want the +, because in this particular case, the
functional notation is klunky.

Much the same considerations apply to +:= and that's why it is
reasonable to have a special case for infix operators in this situation.

You don't want to generalize if the generalization has a negative effect
on the 99% common use case, and helps only the remaining 1%.

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

From: Randy Brukardt
Sent: Tuesday, November 3, 2009  8:32 PM

But that argues for *only* supporting +:= and forgetting the rest of the
operators. None of the other cases are at all likely. And in any case,
we aren't going to support all of the operators in this form:

    **:= is ugly

but the operators that are reserved words don't work at all. I surely
hope we aren't going to allow stuff like:

    mod:=
    and:=

and so on. Those aren't possible to lex in any reasonable way, and parsing
doesn't have enough information (it doesn't see whitespace) to check the
difference between "and:=" and "and :=".

So, no matter what we do, we're going to have a very warty design if you
just try to support this in assignment.

I'm sympathetic to the concern about usability, but I really don't want to
see an amazingly inconsistent design in Ada.

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

From: Edmond Schonberg
Sent: Tuesday, November 3, 2009  8:33 PM

I was thinking about it, (I mean "it")  but like you I don't think this small
convenience deserves a new keyword. Maybe we should limit ourselves to op:=
syntax for the predefined binary operators, and not try to generalize this
to the power of lambda expressions!

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

From: Tucker Taft
Sent: Tuesday, November 3, 2009  8:54 PM

It would be simplest to parse "<op>:="
as two separate tokens, and allow white
space between the operator and the ":="
if that is what the user chooses to write.

It doesn't seem so bad to write:

   A(I) mod := 7;

to mean

   A(I) := A(I) mod 7;

In some ways, it almost seems more elegant to
write:

    B(Z) + := 3;

than to jam the two symbols together into "+:=".

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

From: Robert Dewar
Sent: Wednesday, November 4, 2009  7:10 AM

> But that argues for *only* supporting +:=

and of course -:= which is just as common

> and forgetting the rest of the
> operators. None of the other cases are at all likely. And in any case,
> we aren't going to support all of the operators in this form:
>
>     **:= is ugly

I would include all the operators, since it is trivial to implement them all.

> but the operators that are reserved words don't work at all. I surely
> hope we aren't going to allow stuff like:
>
>     mod:=
>     and:=
>
> and so on. Those aren't possible to lex in any reasonable way, and
> parsing doesn't have enough information (it doesn't see whitespace) to
> check the difference between "and:=" and "and :=".

I don't see any difficulty in implementation at all. There are two choices.

Either you require no space in between the operator and the :=, in which case it
is trivial to deal with mod:= etc in a lexical analyzer (I cannot even imagine
what difficulty Randy is referring to .. ideed this rule would be similar to C,
that you always parse out the longest token that matches.

Or, you allow spaces in between the tokens in which case the parser can handle
this just fine (there is no current legal code in which you can see mod and :=
tokens adjacent, so no problems arise).

You could even at least in GNAT require no spaces and handle it in the parser,
since we keep source locations of all tokens (I am surprised at any compiler
that does not do that), but in any case this third approach is inferior to the
other two.

So I see zero implementation difficulty here.

> So, no matter what we do, we're going to have a very warty design if
> you just try to support this in assignment.
>
> I'm sympathetic to the concern about usability, but I really don't
> want to see an amazingly inconsistent design in Ada.

I find allowing quite generally

operator :=

(with or without spaces allowed, I don't care), that doesn't seem warty. Any of
the more general notations seem much less convenient with no compensatory gain.

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

From: Robert Dewar
Sent: Wednesday, November 4, 2009  7:11 AM

> In some ways, it almost seems more elegant to
> write:
>
>     B(Z) + := 3;
>
> than to jam the two symbols together into "+:=".

Seems reasonable to me, I would be quite happy to allow (but of course not
require) spaces.

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

From: John Barnes
Sent: Monday, November 9, 2009  11:02 AM

> Here is a hand-drawn Algol 68 syntax chart from an old ACM
> Communications.  It shows both "<op>:=" and "<op>=:" (I think!):
>
>    http://www.sofport.com:5055/ARG/algol-68-p39-peck.pdf

This is obviously now water under the bridge but my (dusty) copy of the draft
report on Algol 68 does not seem to have =:

It does have :=: meaning "is".

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

From: Brad Moore
Sent: Thursday, November 5, 2009  11:15 AM

Another possibility that may not have been considered:

Instead of trying to come up with a shortcut for eliminating the first primary
of the RHS, how about eliminating the LHS instead?

e.g.

X + 5;

If one were asked what such a statement would do, it's pretty difficult to come
up with anything other than:  Add 5 to X;

X ** 2; -- Square X
-X / 3.0;  -- Negate X and divide it by 3.0

or

X + 5 * 2 + f(Y);  -- Add 10 times the result of F to X.

etc

We wouldn't want to be able to say
X = 2;

of course, otherwise we would be introducing a bunch of C vulnerabilities such
as confusion between comparison and assignment for =.

However, if we were to define an assignment statement as;

   assignment_statement ::= variable_name := expression; | assignment_expression;

Then say that an assignment_expression is a simple_expression where the first
primary is a variable_name, such that an assignment_expression is a shortcut
for:
  variable_name ::= assignment_expression where variable_name
is the first primary of the assignment_expression;

.Then, maybe this could work. This would allow all operators other than
relational operators (= /= < > <= >=) and logical operators (and or xor).

If we are open to approaching this in a non-C way, could this be viewed as
perhaps better than C? Or are there syntactic problems that would rule out this
approach?

For example, I find;
     X ** 2;
easier to parse mentally than
     X ** := 2;

But perhaps that is just me.

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

From: Pascal Leroy
Sent: Sunday, November 15, 2009  9:31 AM

> Maybe the digraph <- could be used for this purpose:
>
> A.B := F (<-,  <-);
>
> A (X) := <- + 1;
>
> intuitively it hints at its purpose by pointing to the left-hand side in the
> assignment.

Intuitively it looks like a smiley and it can surely be used to construct some
obfuscated source code:

A := F((<-=><-*<-))**<-;

FWIW, I agree with everything that RBKD said on this thread.  Please stick to
what programmers expect (ie +:= by analogy to += in just about every language)
and please support all operators (I certainly use |= and &= all the time in
C++).

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

From: Bob Duff
Sent: Sunday, November 16, 2009  5:20 PM

> Intuitively it looks like a smiley and it can surely be used to
> construct some obfuscated source code:
>
> A := F((<-=><-*<-))**<-;

I don't buy the "can be used to obfuscate" argument.
I only buy the "can be used to obfuscate, BY ACCIDENT" argument.

By the way, I don't think the "<-" on the left-hand side of a "=>" in an
aggregate would be legal, according to Gary's proposal (with Ed's modification
that uses the "<-" syntax). We're not talking about some sort of macro
substitution, here.

> FWIW, I agree with everything that RBKD said on this thread.  Please
> stick to what programmers expect (ie +:= by analogy to += in just
> about every language) and please support all operators (I certainly
> use |= and &= all the time in C++).

So you've been writing a bit of C++ code lately, eh?  ;-)

I prefer: Do nothing.

Second choice: Do something, but make it fairly general --- a way to refer to
the left-hand side of the assignment.

Third choice: +:= and the like.  I agree that if we're going to do that, it
should apply to all operators.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  11:52 AM

> I prefer: Do nothing.

A pity, since the third choice here would be useful both in making code easier
to read and write.

> Second choice: Do something, but make it fairly general --- a way to
> refer to the left-hand side of the assignment.

I find all the proposals of this nature highly distasteful. I would rather do
nothing than introduce such a junky syntax.

> Third choice: +:= and the like.  I agree that if we're going to do
> that, it should apply to all operators.

Such an easy and straightforward proposal, why not?

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

From: Robert Dewar
Sent: Monday, November 16, 2009  11:53 AM

> Second choice: Do something, but make it fairly general --- a way to
> refer to the left-hand side of the assignment.

Part of the reason I hate this, is that in practice the simple cases of
operators will make up 98% of the use of this feature, and any general notation
will make this common usage harder to write and read.

Furthermore, the idea of having somethingf like a <- buried deep in an
expression to mean the left hand side is

a) obscure from a code understandability point of view
b) annoying to implement, since it introduces a really odd context dependence.

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

From: Randy Brukardt
Sent: Monday, November 16, 2009  12:23 PM

> I prefer: Do nothing.

I strongly agree with Bob here. Three reasons for that:
* Robert has made a strong enough case that what Bob calls the second choice
  here would be hard to read and understand;
* This Amendment is getting clogged full of everybody's "nice to haves"; we're
  going to have to draw a line somewhere or this Amendment is going to get way
  too large (or we're going to start dropping important stuff in favor of "nice
  to haves", which is the wrong way to go);
* Symbols like "and:=" are a lexical nightmare. Any way to recognize them
  properly requires a distasteful hack to a lexer (and I think requiring later
  parts of the compiler to know about whitespace between tokens is a distasteful
  hack);
* Ada is refreshingly free of special-case gizmos, and these C operators are the
  worst kind, IMHO. Other than +:=, you'd hardly ever even remember to use them.

P.S. Yes, I noticed I can't count. ;-)

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

From: Bob Duff
Sent: Monday, November 16, 2009  1:03 PM

> > I prefer: Do nothing.
>
> I strongly agree with Bob here.

For the record, I only weakly agree with myself here.  That is, I can live with
any of the three solutions I mentioned.

>... Three reasons for that:
> * Robert has made a strong enough case that what Bob calls the second
>choice  here would be hard to read and understand;
> * This Amendment is getting clogged full of everybody's "nice to
>haves";  we're going to have to draw a line somewhere or this Amendment
>is going to  get way too large (or we're going to start dropping
>important stuff in favor  of "nice to haves", which is the wrong way to
>go);

Yeah, it would certainly be a shame for this to cause us to drop (for example)
user-defined subtype constraints/predicates/whatever-they're-called. Or even
case expressions, which are more in the nice-to-have category -- VERY nice to
have.

> * Symbols like "and:=" are a lexical nightmare. Any way to recognize
> them properly requires a distasteful hack to a lexer (and I think
> requiring later parts of the compiler to know about whitespace between
> tokens is a distasteful hack);

I don't buy this one.  It seems easy to implement, whether we consider "and:="
to be a single token (with NO spaces allowed) or two tokens (with spaces
allowed).  I think I prefer spaces-allowed, as suggested by Tucker.  But if we
do it the other way, I think I'd probably implement it in GNAT allowing spaces
in the lexer, and then give a clear error "no spaces allowed here" rather than
some sort of "parser is hopelessly confused here".

Surely all compilers remember the "source location" of each token, and can
easily check if "and" is immediately followed by ":=".

> * Ada is refreshingly free of special-case gizmos, and these C
> operators are the worst kind, IMHO. Other than +:=, you'd hardly ever
> even remember to use them.

Well, I agree that +:= is the most common case.  But in all cases, there's a
real benefit to not having to worry about duplicating the l.h.s., having to
carefully compare expressions in your head, and having to worry about side
effects.

> P.S. Yes, I noticed I can't count. ;-)

Number_Of_Reasons + := 1;

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

From: Robert Dewar
Sent: Monday, November 16, 2009  1:17 PM

> * Symbols like "and:=" are a lexical nightmare. Any way to recognize
> them properly requires a distasteful hack to a lexer (and I think
> requiring later parts of the compiler to know about whitespace between
> tokens is a distasteful hack);

This is a completely unconvincing argument.

First the lexical issue is completely incomprehensible. It is absolutely trivial
to deal with these in any reasonable lexer, and if you are using a lexer like
flex, it is of course trivial (since there is a standard option, needed of
course for C, to always recognize the longest token). If by some devious design
your compiler cannot handle this, I don't see that design short-coming as having
a legitimate influence here.

Second, at least Tuck and I feel that it would be a mistake to require no white
space, and that it is perfectly reasonable to allow:

    X + := 3;

and indeed may even read better

> * Ada is refreshingly free of special-case gizmos, and these C
> operators are the worst kind, IMHO. Other than +:=, you'd hardly ever
> even remember to use them.

Well -:= is of course just as common, but it is indeed for the overwhelminingly
common cases of +:= and -:= that you use these constructs.

I find nothing here that is a "special-case gizmo", this notation has been
familiar for decades in Algol-68, and C languages, as well as those languages
whose syntax is derived from C.

On the contrary, I find it plain horrible to have to write

    A (J, J, L + 3) := A (J, J, L + 3) + 1;

and make the reader carefully compare the two references, and

    declare
       Elmt : Integer renames A (J, L, L + 3);
    begin
       Elmt := Elmt + 1;
    end;

is alwfully heavy.

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

From: Tucker Taft
Sent: Monday, November 16, 2009  1:18 PM

I think I agree with you Randy.

But as far as the lexical issue, treating them as two separate tokens seems
fine, so the white space would be optional between "and" and ":=" in "X and :=
B;".  Neither the lexer nor the parser would have to jump through any hoops.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  1:27 PM

That's my preference too, I definitely think that

   A and := 16#FF#;

reads as well or better than

   A and:= 16#ff;

particularly if your normal lexical style is to put blanks around all binary
operators, as we do in GNAT, so we would always write

   A := A and (expr);

not

   A := A and(expr);

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

From: Robert Dewar
Sent: Monday, November 16, 2009  1:28 PM

> I think I agree with you Randy.

Are you agreeing with the ordering  nothing > fancy version > simple version?

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

From: Robert Dewar
Sent: Monday, November 16, 2009  1:31 PM

I must say it seems a shame that the ARG ends up putting all kinds of marginally
useful and very complex stuff into the language that no one needs (like 32 bit
characters and leap seconds), and contemplates balking on something very simple
trivial to implement that would be useful ;-) :-)

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

From: Tucker Taft
Sent: Monday, November 16, 2009  2:13 PM

I agree that it is probably not worth making the change, since it doesn't add
significant functionality, and it will create more chances for "idle" use of
features not present in Ada 95 compilers.  If you are going to use a new feature
and cut yourself off from all the Ada 95 compilers out there, it probably ought
to be an important new functionality.

If more of the Ada vendors were closely following the changes we were proposing
then I would feel differently, but as it is, GNAT and Rational (and perhaps
Irvine?) are the only Ada vendors I know of that have made a significant effort
to even implement the Ada 2005 features.  And Rational hasn't announced a date
when they will release their Ada 2005 stuff...

If we make the change, I prefer the "<op> :=" approach to any other.

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

From: Tucker Taft
Sent: Monday, November 16, 2009  2:47 PM

A new reserved word to represent the LHS of an assignment...  E.g. "self" or
"LHS"?

    X := self + 2;

or

    X := LHS + 2;

"self" isn't too bad, though I worry that some folks might interpret it as the
"current instance" or the controlling parameter.

Although I am not in favor of the whole idea, if it were done I would rather
have something that really stands out, because it isn't used anywhere else in
the language, such as:

     X := () + 2;

  or

     X := Union((), Y);

But it still feels too much like a syntactic "trick" that doesn't belong in a
language emphasizing readability.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  3:22 PM

> Just because it's one of many such.  I'd feel differently if there
> were more than one complete implementation of Ada right now.

But the scale of things here is so small, this is a couple of hours work.
Constrast that with leap seconds which tool a couple of person months and is as
far as I can tell totally useless (since none of the OS's in common use supports
leap seconds).

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

From: Robert Dewar
Sent: Monday, November 16, 2009  3:30 PM

Also I don't really buy the argument that Tuck makes about Ada 95
incompatibility. We have introduced SO much stuff post Ada 95 that in practice
anyone who is not specifically concerned with Ada 95 backwards compatibility
will quickly step past this barrier.

If you are interested in Ada 95 compatibility, you simply use the Ada 95 mode in
GNAT (it is still actually the default for GNAT Pro, though the public versions
default to Ada 2005).

If you set Ada 2005 mode (or Ada 201x mode, pretty soon we will have to make a
choice of the name so we can implement a switch), then a zillion things will
take you out of range of Ada 95 compilers, the +:= notation will not make things
any worse in this regard.

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

From: Pascal Leroy
Sent: Monday, November 16, 2009  2:06 PM

> So you've been writing a bit of C++ code lately, eh?  ;-)

True, but not very relevant.  I have thought for a long time that the assignment
shorthands in C/C++ are a nice readability feature, and that having to repeat
the variable name on the rhs in Ada is unnecessarily obscuring the code.

Where C++ screw up big time is that you can redefined +=, ++, + and =
independently of each other.

> I prefer: Do nothing.

I can see the argument that it has been like that forever and that Ada
programmers have gotten used to it, and that you don't need more bells and
whistles.  On the other hand, it seems that it's a fairly simple feature to
define and implement.

> Second choice: Do something, but make it fairly general --- a way to refer to
> the left-hand side of the assignment.

Either you'd have to have a new keyword (which is unappealing the reasons that
you and others have mentioned) or you'd have to have some kind of "smiley"
symbols, which would not help readability.  So your second choice looks
overengineered to me.

PS: Regarding "obfuscate by accident", do you really want to write:

  Some_Variable := <- - 1;

Seems rather abstruse to me, and it's a very basic use case.

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:30 PM

> > So you've been writing a bit of C++ code lately, eh?  ;-)
>
> True, but not very relevant.  I have thought for a long time that the
> assignment shorthands in C/C++ are a nice readability feature, and
> that having to repeat the variable name on the rhs in Ada is
> unnecessarily obscuring the code.

I agree.  Repeating code is evil.  Even in this small-scale case.

> Where C++ screw up big time is that you can redefined +=, ++, + and =
> independently of each other.

Well, maybe, but Ada allows the same sort of thing, where you can redefine + and
- so that (X - Y) /= (X + (-Y)), and (X < Y) /= (not (X >= Y)) and so on.

Ada solves that problem only for = and /=.

> > I prefer: Do nothing.
> >
>
> I can see the argument that it has been like that forever and that Ada
> programmers have gotten used to it, and that you don't need more bells
> and whistles.

Exactly.

>...On the other hand, it seems that it's a fairly simple feature to
>define and implement.

True.

If a vote were taken today in favor of the +:= alternative, I guess I'd abstain.

...
> PS: Regarding "obfuscate by accident", do you really want to write:
>
>   Some_Variable := <- - 1;
>
> Seems rather abstruse to me, and it's a very basic use case.

I admit that's kind of ugly.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  5:42 PM

> Well, maybe, but Ada allows the same sort of thing, where you can
> redefine + and - so that (X - Y) /= (X + (-Y)), and (X < Y) /= (not (X
> >= Y)) and so on.

Sure, but sometimes that flexibility is OK, take booleans

    A + B

and

    -A

pretty clearly is NOT

But A - B

does not mean A or (not B)

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

From: Pascal Leroy
Sent: Monday, November 16, 2009  2:11 PM

> * This Amendment is getting clogged full of everybody's "nice to haves";
> we're going to have to draw a line somewhere or this Amendment is going to
> get way too large (or we're going to start dropping important stuff in favor
> of "nice to haves", which is the wrong way to go);

This is a very valid concern.  I am only following this list rather
intermittently these days, but it's looking like the next Amendment will have at
least as much stuff as Ada 2005, and to be frank a good part of it seems
superfluous to me.  Good luck to the implementers!

> * Symbols like "and:=" are a lexical nightmare. Any way to recognize them
> properly requires a distasteful hack to a lexer (and I think requiring later
> parts of the compiler to know about whitespace between tokens is a
> distasteful hack);

FUD, FUD, FUD.  There are good argument against this feature, but the lexer
complexity is not one of them.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  3:58 PM

As a test of two notations consider the following

a)   X := X - 1;
b)   X -:= 1;
c)   X := <- - 1;

I would prefer b) over a), even in this one charactert identifier case. But I
certainly would not prefer c) over a). Sure you could consider using c if the
lhs gets nastily complex, but the nice thing about b) is that it is so neat
compact and readable, that it is a pleasant replacement *even* for the case of a
one character identifier.

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:02 PM

> A new reserved word to represent the LHS of an assignment...  E.g.
> "self" or "LHS"?

Yeah, something like that.  I've suggested "idem" or "it"
in the past.

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:07 PM

> If you set Ada 2005 mode (or Ada 201x mode, pretty soon we will have
> to make a choice of the name so we can implement a switch), ...

I believe ARG or WG9 or somebody decided that the semi-official name is Ada
2012.  I wasn't in on that decision, so I've no idea why it isn't the usual
previous-version-plus-10-years.

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

From: Dan Eilers
Sent: Monday, November 16, 2009  4:10 PM

> Either you'd have to have a new keyword (which is unappealing the
> reasons that you and others have mentioned) or you'd have to have some
> kind of "smiley" symbols, which would not help readability.  So your
> second choice looks overengineered to me.

Using Robert Dewar's example:

> On the contrary, I find it plain horrible to have to write
>
>     A (J, J, L + 3) := A (J, J, L + 3) + 1;
>
> and make the reader carefully compare the two references, and
>
>     declare
>        Elmt : Integer renames A (J, L, L + 3);
>     begin
>        Elmt := Elmt + 1;
>     end;
>
> is alwfully heavy.

We could allow a renames inside an expression, like this assignment statement:

     Elmt : Integer renames A (J, L, L + 3) := Elmt + 1;

That would avoid introducing any new symbols or a new keyword, while avoiding
the heavy block statement.

It also solves the related problem in IF statements:

     if Elmt : Pointer renames A (J, L, L + 3) /= null then
        Elmt := Elmt.Next;
     end if;

Arguably, you could probably omit the ": type_name".

As a side benefit, this notation would be heavy enough so that users wouldn't be
tempted to use it for the simplest cases which are already perfectly readable.

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:12 PM

> > Just because it's one of many such.  I'd feel differently if there
> > were more than one complete implementation of Ada right now.
>
> But the scale of things here is so small, this is a couple of hours
> work.

Nothing's stopping you from implementing it under the extensions switch.  ;-)

If you were so inclined, you could even implement an optional warning:

    X (A, B, C) := X (A, B, C) + 1;
                ^ Consider "+ :=" operator

with auto-fix...

>...Constrast that with leap seconds which tool a couple of person
>months and is as far as I can tell totally useless (since none of the
>OS's in common use supports leap seconds).

I agree 100% about leap seconds.  A complete waste of time.
It's partly my (over?)reaction to that sort of thing that is making me a
nay-sayer these days about adding not-so-important features.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  4:17 PM

>> If you set Ada 2005 mode (or Ada 201x mode, pretty soon we will have
>> to make a choice of the name so we can implement a switch), ...
>
> I believe ARG or WG9 or somebody decided that the semi-official name
> is Ada 2012.  I wasn't in on that decision, so I've no idea why it
> isn't the usual previous-version-plus-10-years.

Great, GNAT will go with 2012 and that will be that :-)

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

From: Robert Dewar
Sent: Monday, November 16, 2009  4:19 PM

> Nothing's stopping you from implementing it under the extensions
> switch.  ;-)

We traditionally have not implemented such extensions until there is a
reasonable consensus (e.g. as for conditional expressions).

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

From: Tucker Taft
Sent: Monday, November 16, 2009  4:32 PM

There is a fair amount of noise about the Mayan calendar predicting the end of
the world (or equivalent?) in 2012, so that makes the number a bit more
"interesting" than it would be otherwise.

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:47 PM

If you go to:

    www.nasa.gov

and scroll down, look in the lower left corner and there's some links titled
"No, The World Isn't Going to End in 2012."

I didn't read much of it -- debunking of foolish nonsense gets tiresome after a
while.

By the way, I remember you mentioned to me near the end of the Ada 9X project
that you didn't much like the name "Ada 95", because it reminded people of
"Windows 95".  ;-)

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

From: Robert Dewar
Sent: Monday, November 16, 2009  5:00 PM

> By the way, I remember you mentioned to me near the end of the Ada 9X
> project that you didn't much like the name "Ada 95", because it
> reminded people of "Windows 95".  ;-)

So you think perhaps Ada 7 would be the right choice? :-)

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

From: Bob Duff
Sent: Monday, November 16, 2009  4:36 PM

> We traditionally have not implemented such extensions until there is a
> reasonable consensus (e.g. as for conditional expressions).

I'm not advocating anything in this particular case.

In general, I suggest we keep our minds open to the possibility of implementing
things first -- then we know something about how hard it is to implement, and
folks can try it out and see how useful it is.

I believe some languages take the attitude that they won't standardize any new
feature without at least one existing implementation.  (The danger, though, is
that you'll get two existing incompatible implementations, and the standards
committee is politically forced to put in too many cases of "not specified by
the standard", which defeats the purpose of a standard.)

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

From: Robert Dewar
Sent: Monday, November 16, 2009  4:59 PM

> In general, I suggest we keep our minds open to the possibility of
> implementing things first -- then we know something about how hard it
> is to implement, and folks can try it out and see how useful it is.

Absolutely, I am for pushing the envelope in this way. Even though it results in
missteps sometimes. GNAT for instance implemented with type, which was abandoned
(and removed from GNAT), and the pragma form of pre/postconditins (which will of
course be retained anyway). I am certainly fine with implementing things on an
experimental basis.

But in the case of +:=, the implementation is completely trivial, a couple of
hours work at most, and we know exactly the issue from a usability point of
view, so I would be inclined to wait a bit to see how the current energetic
debate ends up.

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

From: Bob Duff
Sent: Monday, November 16, 2009  5:10 PM

> As a test of two notations consider the following
>
> a)   X := X - 1;
> b)   X -:= 1;
> c)   X := <- - 1;
>
> I would prefer b) over a), even in this one charactert identifier
> case. But I certainly would not prefer c) over a). Sure you could
> consider using c if the lhs gets nastily complex, but the nice thing
> about b) is that it is so neat compact and readable, that it is a
> pleasant replacement *even* for the case of a one character
> identifier.

To me, if the lhs is a single identifier, the issue is unimportant.
Sure, I agree b) is more readable than a), but it's not worth learning about an
extra syntactic gizmo.

The cases I find much more compelling are when the lhs is a complicated name --
especially when I can't immediately tell by looking at it whether it has side
effects.

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

From: Robert Dewar
Sent: Monday, November 16, 2009  5:39 PM

Yes, of course everyone agrees on this, the above is just my illustration of how
much more convenient the b) syntax is than the c) syntax.

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

From: Bob Duff
Sent: Monday, November 16, 2009  8:09 PM

> > A new reserved word to represent the LHS of an assignment...  E.g.
> > "self" or "LHS"?
>
> Yeah, something like that.  I've suggested "idem" or "it"
> in the past.

Bill said, out of the blue, that the problem with programming is so much
repetitive work, and having to duplicate code (he showed me an example of
duplicated code on his programmable calculator, written in some sort of weird
assembly language I don't understand).  Duplicate code is what this AI is all
about, so I explained this AI to him, with this example:

    A(I).all.B := A(I).all.B + 1;

His response was that it should be:

    A(I).all.B := itself + 1;

But, I said, we don't want a new reserved word "itself", so existing code can
still work.

He then suggested:

    A(I).all.B :+ 1;

I said we were considering +:= , and he had some explanation I didn't understand
why :+ is better.

That's a non-language-lawyer view!  ;-)

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

From: Edmond Schonberg
Sent: Tuesday, November 17, 2009  9:19 AM

The argument on the importance of avoiding repetition is the one that matters.
If we were starting from scratch, a new keyword would help (my preference would
be "it" but today that is not an option).  I think that choosing a familiar
syntax in this case is actually a positive move: there is no point in looking
different when there is a convergence of syntactic conventions among leading
languages (looking different for its own sake is counterproductive, and is the
road to APL).  Given that the implementation costs are negligible, I lean
towards adopting the familiar:

A (B),X (5) +:= 1;

extended to all binary operators.   The next edition of  our favorite
pedagogical presentation of the language can emphasize the usefulness of
renaming declarations with examples such as

declare :
   it : T := Some_Complex_Name;
begin
   it := Complex_Function (it);
end;

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

From: Tucker Taft
Sent: Tuesday, November 17, 2009  9:29 AM

I presume you meant "A(B).X(5) +:= 1;"
and "it : T renames Some_Complex_Name;"

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

From: Edmond Schonberg
Sent: Tuesday, November 17, 2009  10:29 AM

Indeed.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  9:30 AM

(idle discussion, ignore if in fierce relevancy mode)

> declare :
>    it : T := Some_Complex_Name;
> begin
>    it := Complex_Function (it);
> end;

I must say that here the declare/begin/end seem horrible noise. I am of course
not suggesting a change in the language, but I never understood NW's aversion to
mixing declarations and statements. To me it is just fine to write

      it : T renames Some_Complex_Name;
      it := Complex_Function (it);

BTW it is interesting to see Ed forgetting the renames, shows the dangers here,
the above declare block is valid but completely useless. Luckily GNAT will at
least warn of a useless assignment here :-)

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

From: Bob Duff
Sent: Tuesday, November 17, 2009  9:41 AM

> To me it is just fine to write
>
>       it : T renames Some_Complex_Name;
>       it := Complex_Function (it);

I strongly agree.

However, there are many people who hate that style in languages that allow it,
and many that even hate it when surrounded by declare/begin/end or { ... } or
whatever.  They say they want all the declarations up front, where they can find
them without rummaging around through the code.

I don't think that argument makes any sense, especially in a language like Ada
where declarations often contain executable code.

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

From: Erhard Ploedereder
Sent: Tuesday, November 17, 2009  3:24 AM

I suggest we return to basics here.

 +:=   -:=

Everbody knows and understands them. Many love them.
May I'd add *:= and /:= in deference to my math teacher in public school, but
that's the end of it.

We are risking throwing out a good feature, because we want to make it more
general than it deserves to be.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  11:58 AM

Two details. I would vote in favor of allowing spaces between the operator and
:= since I think that reads nicely in some cases.

(and it prevents Randy's lexical nightmare)

Also, once you have four operators, why not have all of them, seems more uniform
and makes the implementation easier rather than more difficult.

> We are risking throwing out a good feature, because we want to make it
> more general than it deserves to be.

I call this the "systems programmer syndrome". You suggest a simple feature YYY.

Someone says "great, but that's a special case of more general feature XXX". You
say, "OK, I don't need XXX, I only need YYY, but whatever you say",

Then after lots of to-and-fro, it is decided that XXX is too
complicated/awkward/difficult-to-implement, and YYY gets lost.

In this particular case, we have the additional point that the more general
feature is inferior for the common intended use.

I really want to say

    X (I,J,K) +:= 1;

rather than

    X (I,J,K) := it + 1;
or
    X (I,J,K) := <- + 1;

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

From: Bob Duff
Sent: Tuesday, November 17, 2009 12:02 AM

> We are risking throwing out a good feature, because we want to make it
> more general than it deserves to be.

I don't see that.  I haven't heard much complaining that supporting all
operators is somehow much more difficult than support just + and - (or + - * /).

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  12:12 PM

quite the contrary, we would have to have a special test for the allowed
operators, so it would be more work to be selective.

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

From: Randy Brukardt
Sent: Tuesday, November 17, 2009  12:21 PM

...
> We are risking throwing out a good feature, because we want to make it
> more general than it deserves to be.

You are assuming that everyone thinks this is a "good feature". I know I don't
like it aesthetically, and it looks too much like C for my taste.

Moreover, when there was a discussion on exactly this topic on comp.lang.ada a
couple of years ago, there was a vocal contingent against it. It's pretty
obvious that there is a portion of the community that would not be happy to see
this added to Ada.

I think the only way I would vote in favor of adding this would be if bribed (by
a promise to vote for something I find important). Note that I don't find this
feature all that important either way, so I don't consider it a big deal if it
passes over my objections. But that also means that there is no reason to go
along with something that I detest.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  12:36 PM

...
> I think the only way I would vote in favor of adding this would be if
> bribed (by a promise to vote for something I find important). Note
> that I don't find this feature all that important either way, so I
> don't consider it a big deal if it passes over my objections. But that
> also means that there is no reason to go along with something that I detest.

Well I must say I am puzzled by the "detest" here, seems a strange reaction
indeed (and perhaps explains the lexical FUD :-))

To me, this is an A68 feature, which I always found very useful, and I have
always missed it in Ada. I guess it depends how allergic you are to repeated
code (I an very allergic) or to heavy declare usage (I am also very allergic to
that).

> Moreover, when there was a discussion on exactly this topic on
> comp.lang.ada a couple of years ago, there was a vocal contingent against it.

Well my experience is that there is a huge amount of junk on comp.lang.ada, and
I would not give this a moments attention as a significant source of objection.
There is a vocal contingent expressing all kinds of junk opinions there.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  12:38 PM

Note by the way a curious lack of substance in Randy's viewpoint. His arguments
amount fo

"I detest this feature because it looks like C"

"Some comp.lang.ada partipants don't like it"

"It would be hard to implement in my lexical scanner"

Whereas the pro argument is a safety/readability argument, namely to avoid
duplication of code, which is always a liability both from a reading and writing
point of view.

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

From: Randy Brukardt
Sent: Tuesday, November 17, 2009  12:55 PM

> Note by the way a curious lack of substance in Randy's viewpoint.

I wasn't trying to convince anyone. I don't like it on an aesthetic level, and
I'm not voting for it. I don't expect anyone else to feel the same way -- beauty
is very subjective.

...
> Whereas the pro argument is a safety/readability argument, namely to
> avoid duplication of code, which is always a liability both from a
> reading and writing point of view.

This argument wasn't compelling to Ichbiah, and I don't see what has changed in
the intervening 30 years. So I don't find it compelling, either.

Several people tried to find alternatives more in the spirit of Ada, and
*you* complained that you don't like their aesthetics. Fair enough; in that case
this problem (which is *waaaay* down on the priority scale) doesn't need to be
solved.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  7:09 PM

I don't see these alternatives as being more in the spirit of Ada, especially
<-. To me they are failed attempts to generalize a feature that does not require
generalization. the declare/renames solution is fine for more complex cases than
+:= and -:=

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

From: Dan Eilers
Sent: Tuesday, November 17, 2009  12:51 PM

> Whereas the pro argument is a safety/readability argument,

There is also a con safety/readability argument, since allowing +:= would
introduce a situation where a one-character change affects the meaning of a
statement.

Assignment statements would need to be read much more carefully than is
currently the case.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  1:21 PM

> Assignment statements would need to be read much more carefully than
> is currently the case.

Not my experience with Algol-68. But perhaps an argument for a style where you
separate

    A + := 3;

Dan, is this from experience, or a guess?

Note that in return, you have much less careful reading to do in a case like

    X (F (A, B, C + 1)) := X (F (A, B, C + 1)) + 1;

to ensure that the duplicated code is duplicated accurately.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  1:22 PM

> There is also a con safety/readability argument, since allowing +:=
> would introduce a situation where a one-character change affects the
> meaning of a statement.
>
> Assignment statements would need to be read much more carefully than
> is currently the case.

Note by the way that the language is FULL of cases where a one-character change
affects the meaning of a statement, it has never been a principle that
one-character changes should not affect meaning :-)

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

From: Dan Eilers
Sent: Tuesday, November 17, 2009  1:40 PM

> Dan, is this from experience, or a guess?

I don't often read or write code in languages which allow +=, but I often read
code where I wonder if a typo was made which would affect the meaning.

Currently, there is only one kind of assignment statement, and when the lhs is a
single variable, such statements are trivial to read.

The proposal to add a dozen or so different flavors of assignment statement
would inevitably require anyone reading any assignment statement to wonder
whether the right flavor was used.

It would also cause difficulties for coding standards, in trying to decide
whether all occurrences of "x := x + 1" should be changed to "x +:= 1".

> Note by the way that the language is FULL of cases where a
> one-character change affects the meaning of a statement, it has never
> been a principle that one-character changes should not affect meaning
> :-)

Yes, but I consider it harmful to add more such cases.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  7:14 PM

> The proposal to add a dozen or so different flavors of assignment
> statement would inevitably require anyone reading any assignment
> statement to wonder whether the right flavor was used.

You declare, based on what (not experienced by your own admission), that it is
inevtiable that .... However, based on extensive experience in A68 usage, I
never saw this happening at all, let alone being inevitable. You might as well
say that it is inevitable to worry about every occurence of +, wondering whether
it should be some other operator.

> It would also cause difficulties for coding standards, in trying to
> decide whether all occurrences of "x := x + 1"
> should be changed to "x +:= 1".

Well I don't see that as a difficulty, and if you feel you don't like the
feature, simply disallow it in your coding standard!

>> Note by the way that the language is FULL of cases where a
>> one-character change affects the meaning of a statement, it has never
>> been a principle that one-character changes should not affect meaning
>> :-)
>
> Yes, but I consider it harmful to add more such cases.

Seems like a *very* thin argument, there simply is no principle in Ada that one
character changes cannot affect the meaning, and the language is chock full of
such cases, because no attempt was ever made to eliminate them. Yes, we did
deliberately intend (and stated the intention) to avoid cases where punctuation
characters such as ; or , could change the meaning by inclusion/exclusion, but
the design principle never went further than that.

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

From: Erhard Ploedereder
Sent: Tuesday, November 17, 2009  6:34 PM

> I don't see that.  I haven't heard much complaining that supporting
> all operators is somehow much more difficult than support just ...

It is not the compiler writers that I had in mind.
I am very unsure whether I would want to allow
  X mod := 3;
and suchlike for language reasons. (Or maybe even "Y abs :=;"  ;-) )

While it would be moderately useful, if /:= is deemed useful, it just looks
ugly. Subjective opinion, not really backed by scientific argument, other than
the very infrequent use of such constructs.

It is a slippery slope to allow the notation for more than the 4 basic math
operations. I am not talking compiler issues. Indeed, I agree that it makes very
little difference in a compiler to generalize the capability. It is language
complexity that bothers me.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  7:18 PM

> While it would be moderately useful, if /:= is deemed useful, it just
> looks ugly. Subjective opinion, not really backed by scientific
> argument, other than the very infrequent use of such constructs.

well I don't much care, if choosing to limit the feature to the most useful
cases makes it possible to get it in, limit away!

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

From: Tucker Taft
Sent: Tuesday, November 17, 2009  7:29 PM

One of my favorite one-character boo-boos from the era before "use type" was:

    function "+"(Left, Right : P.T) return P.T renames P."+";
    function "-"(Left, Right : P.T) return P.T renames P."+";
    ...

I don't think this <op>:= idea is very important, but it is one of those things
that folks coming from Java or C/C++ notice as being annoying about Ada.  They
have to go from "++X" to "X := X + 1" which gets proportionally worse when "X"
is really "A(B).C(D)".

I'm definitely not recommending pre- or post-increment operations, but "X +:= 1"
seems like a good half-way position in terms of helping both readability and
writability.  I agree it looks a bit odd initially, and may continue to look odd
to some folks forever, but given how often I have seen it in e-mail over the
past week or so ;-), it is already beginning to look more "natural" to me. YMMV!

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

From: Dan Eilers
Sent: Tuesday, November 17, 2009  8:01 PM

> You declare, based on what (not experienced by your own admission),
> that it is inevtiable that .... However, based on extensive experience
> in A68 usage, I never saw this happening at all, let alone being
> inevitable. You might as well say that it is inevitable to worry about
> every occurence of +, wondering whether it should be some other
> operator.

By Murpy's law, what can go wrong will go wrong, and so anyone reading Ada code
will need to be alert to the possibility of a botched compound assignment, where
no such possibility currently exists.

Inevitably, someone will try to change:
        "x := x + 1" into "x +:= x + 1"
or      "x := x - 1" into "x -:= -1"
or will say "x := 1" when they mean "x +:= 1".

> Seems like a *very* thin argument, there simply is no principle in Ada
> that one character changes cannot affect the meaning, and the language
> is chock full of such cases, because no attempt was ever made to
> eliminate them. Yes, we did deliberately intend (and stated the
> intention) to avoid cases where punctuation characters such as ; or ,
> could change the meaning by inclusion/exclusion, but the design
> principle never went further than that.

Besides punctuation, Ada uses names rather than symbols for a lot of operators
(e.g. and, or, xor, not, mod, rem, .all), with the intent of preventing
single-character typos.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  8:37 PM

> Inevitably, someone will try to change:
>         "x := x + 1" into "x +:= x + 1"
> or      "x := x - 1" into "x -:= -1"

Again, just declaring that you think something is inevitable does not make it
so.

> or will say "x := 1" when they mean "x +:= 1".

I have never seen this mistake made in Algol-68, I guess C folks could comment
on the analogous mistake

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

From: Stephen Michell
Sent: Tuesday, November 17, 2009  8:45 PM

The problem is that C folks have always used such formats, but Ada has hundreds
of millions of lines of code that are written as X := X + N; and under
maintenance somebody is going to want to write X += N; but is going to screw it
up - many, many times. If we are going to head down this shortcut road, we will
probably need a rule that the expression on the left of a shorthand assignment
cannot be repeated on the right.

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

From: Robert Dewar
Sent: Tuesday, November 17, 2009  9:10 PM

That rule belongs in a coding style document, not in the language, it would be
an ugly rule in the language. And surely people would use a refactoring tool for
such changes? I certainly would.

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

From: Stephen Michell
Sent: Tuesday, November 17, 2009  9:25 PM

Not good enough. We are trying to tighten up the language for safety and
correctness, and then we go and add something that has considerable potential
for mistakes.

X + := X + N; will result in X(new) = 2X + N.
X - := -N will result in X (new) = X + N;

Neither of these are obvious from the code. One of the real strengths of Ada it
is exceptionally clear to read and interpret.

All that being said, however, the first case would work with the rule that I
proposed; the second one wouldn't. So it is obvious to me that this proposal for
shorthand assignment doesn't cut muster.

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

From: Brad Moore
Sent: Tuesday, November 17, 2009  9:57 PM

> Inevitably, someone will try to change:
>         "x := x + 1" into "x +:= x + 1"
> or      "x := x - 1" into "x -:= -1"
> or will say "x := 1" when they mean "x +:= 1".


Also, I think

X -:= Y + 1;

Would be an example of a new vulnerability for the language.
I can see people getting confused between interpreting this as

X := X - (Y + 1);

or

X := X - Y + 1;

If you write this out the old way;

X := X - Y + 1;

The reader will not get confused.

Also, I find adding a space between the assignment symbol and the operator,
though it may only be a separation of a few millimeters, feels like a distance
of several meters.

E.g.

A + := 2;

Looks and feels like we are assigning 2 to some weird expression on the LHS.

A +:= 2;

At least makes it more clear that there is a special kind of assignment taking
place.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  6:33 AM

Brad Moore wrote:

> X -:= Y + 1;

For any construct in the language, you can show examples of confusing misuse. I
will say that in the A68 environment, I have NEVER seen misuses of the kind that
people use to argue against this feature. Indeed 99% of the uses are a single
token on the right side, most usually 1.

It is a pity to shoot down these useful uses by FUD about cases that will never
happen in practice. But I can see this FUD succeeding, oh well, we lived without
IN OUT parameters in functions for decades because of similar FUD :-)

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

From: Stephen Michell
Sent: Wednesday, November 18, 2009  10:11 AM

How about a different approach. Suppose we add an attribute 'increment which can
take a paramater that is the amount if the amount is not +1.
Hence we could say
     X(I,j,k)'increment(2);
The type of the parameter to increment would bbe of the same type as the object
being incremented. We could let increment be overridden to produce other
situations, such as a product.

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

From: Stephen Michell
Sent: Wednesday, November 18, 2009  10:16 AM

Maybe instead of 'increment, we could use 'Step.

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

From: Tucker Taft
Sent: Wednesday, November 18, 2009  10:26 AM

Or "'Bump".  There is also a long tradition of short attribute names (e.g. 'Val,
'Pos), so we could use 'Inc and 'Dec without feeling like we are being evil.

If the attribute name is sufficiently short, this seems like an interesting
alternative.  I certainly would *not* allow it to be overridden.  That seems
like a recipe for abuse.  I would allow it to be applied to any scalar type,
including enumeration types, where it would be equivalent to a corresponding
sequence of Enum'Succ or Enum'Pred.  That is:

    X'Inc(3);

would be equivalent to:

    X := Enum'Succ(Enum'Succ(Enum'Succ(X)));

I might suggest that we have a parameter name of "By"
so you could write:

    X'Inc(By => 3);

This certainly feels more "Ada-like" than the symbol combinations we have been
considering.

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  10:28 AM

If untagged classes had survived in Ada 9X, then one could say:

    procedure Incr
       (X : in out root_integer'Class; By : root_integer'Class := 1);
    -- In the root package of my application.

    Blah : My_Int := 0;

    Incr (Blah);
    Incr (Blah, By => 2);

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  10:46 AM

But why would anyone think this clearer than

       Blah := Blah + 2;

which is shorter. Sure I know that these heavy alternative notations might still
possibly be convenient for sufficiently complex left sides.

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

From: Stephen Michell
Sent: Wednesday, November 18, 2009  10:32 AM

But we already have replaceable attributes for 'Read and 'Write. Why not 'Incr?

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  10:34 AM

> How about a different approach. Suppose we add an attribute 'increment
> which can take a paramater that is the amount if the amount is not +1.
> Hence we could say
>      X(I,j,k)'increment(2);

For me I would prefer nothing rather than this very awkward notation. I don't
think it would be much used in practice, and it would seem so clunky compared
with the convenient feature in competing languages. If our point is that we like
verbose in Ada, then

       X(I,J,K) := X (I,J,K) + 2;

is fewer characters than the suggested form, and more convenient to write.

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  10:42 AM

> I might suggest that we have a parameter name of "By"
> so you could write:
>
>     X'Inc(By => 3);

I'd prefer to call them Incr and Decr, and have a default of 1 for By:

    A(I, J)'Incr;
    A(I, J)'Decr(By => 3);

> This certainly feels more "Ada-like" than the symbol combinations we
> have been considering.

The syntax feels more Ada like.  To me, it reads better than anything else
that's been suggested.

But it would be more Ada-like to make it an attribute of the type:

    My_Integer'Incr(A(I, J));
    My_Integer'Decr(A(I, J), By => 3);

That partly defeats the purpose of having a terse notation for a common
operation.  That's why GNAT has "A(I, J)'Img" as a shorthand for
"My_Integer'Image(A(I, J))".

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  10:47 AM

> I'd prefer to call them Incr and Decr, and have a default of 1 for By:
>
>     A(I, J)'Incr;
>     A(I, J)'Decr(By => 3);
>
>> This certainly feels more "Ada-like" than the symbol combinations we
>> have been considering.

A'Incr is at least better than nothing, so that means it is reading more
positively on my scale. I would still prefer the +:= but could live with Incr
and Decr.

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

From: Randy Brukardt
Sent: Wednesday, November 18, 2009  1:20 PM

> But why would anyone think this clearer than
>
>        Blah := Blah + 2;
>
> which is shorter. Sure I know that these heavy alternative notations
> might still possibly be convenient for sufficiently complex left
> sides.

But that applies equally to all of these proposals. Why anyone would think that

       Blah + := 2;

is clearer than

       Blah := Blah + 2;

escapes me. I've always assumed that is why Jean left some shorthand out of Ada.

But I have some sympathy for having a shorthand for:

       Domain_Info(I).Appearance_Count := Domain_Info(I).Appearance_Count + 1;

(a statement I pulled directly from my spam filter).

       Domain_Info(I).Appearance_Count'Inc(1);

seems like an improvement.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  1:25 PM

> But that applies equally to all of these proposals. Why anyone would
> think that
>
>        Blah + := 2;
>
> is clearer than
>
>        Blah := Blah + 2;
>
> escapes me. I've always assumed that is why Jean left some shorthand
> out of Ada.

*any* C programmer or *any* Algol 68 programmer would prefer the short form, and
would regard it as bad style to write the second one. Randy I guess you have
just been writing Ada too much! I think Jean just left it out because there was
no strong push to put it in (I don't remember any push at all), and it was not
in Pascal or LIS.

> But I have some sympathy for having a shorthand for:
>
>        Domain_Info(I).Appearance_Count :=
> Domain_Info(I).Appearance_Count + 1;
>
> (a statement I pulled directly from my spam filter).
>
>        Domain_Info(I).Appearance_Count'Inc(1);
>
> seems like an improvement.

Indeed, the appearence of such horrible cases of code duplication in real Ada
code is

a) worrisome

b) shows that the declare block is just too heavy in practice to be used

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

From: Dan Eilers
Sent: Wednesday, November 18, 2009  11:08 AM

I don't think there has been any mention of overloading resolution implications
for the shorthand proposals, given that Ada allows the lhs of an assignment to
be ambiguous.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  11:16 AM

I would think that

   X'Incr

is simply ambiguous if X is ambigous, no big deal

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

From: Dan Eilers
Sent: Wednesday, November 18, 2009  11:20 AM

I was worried more about the earlier proposals like:

        f(x).all +:= 1;
        f(x).all := itself + 1;

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

From: Edmond Schonberg
Sent: Wednesday, November 18, 2009  11:37 AM

There is no possible difference in overload resolution between these forms and
the current  (duplicated) forms:  the possible interpretations of the left-hand
side are those of the name, those of the right-hand side are those for the
operation (obtained bottom-up from those of the name, the visible operator, and
the literal) and successful resolution means that there is a single common
interpretation between the two.

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

From: Dan Eilers
Sent: Wednesday, November 18, 2009  11:52 AM

I think this causes a significant impact to the overload resolution algorithm if
the type of the lhs not only has to match the type of the rhs, but also the type
of a subexpression of the rhs.

If "itself" can appear more than once on the rhs, that makes it even worse.

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

From: Pascal Leroy
Sent: Wednesday, November 18, 2009  12:34 AM

> I suggest we return to basics here.
>
>  +:=   -:=
>
> Everbody knows and understands them. Many love them.
> May I'd add *:= and /:= in deference to my math teacher in public school,
> but that's the end of it.

Actually "/:=" is the less pleasant of the lot, because it looks too much like
"/=" (note that this similarity is not a problem in C).

I would like to make an argument in favor of "and:=" and "or:=", because I seem
to write A := A or B quite often, but then this begs the question of whether
short-circuit forms should be allowed:

A or else := B;

Hmm, not sure I like that.

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

From: Pascal Leroy
Sent: Wednesday, November 18, 2009  1:13 AM

>> Inevitably, someone will try to change:
>>        "x := x + 1" into "x +:= x + 1"
>> or      "x := x - 1" into "x -:= -1"
>
> Again, just declaring that you think something is inevitable does not
> make it so.
>
>> or will say "x := 1" when they mean "x +:= 1".
>
> I have never seen this mistake made in Algol-68, I guess C folks
> could comment on the analogous mistake

I don't recall seeing any of these mistakes in C/C++ code either.  The most
common mistake regarding operators in C is of course the use of = instead of ==
in if or while statements.

C programmers are not complete lunatics, and they tend to use these shorthands
when it makes sense.  I have seen:

x += 2;  // Very often.
x += y;  // Sometimes.
x |= y;  // Sometimes.
x /= y;  // A few times.
x ^= y;  // Never
x -= -y;  // Are you mad?

So while we can conjure up all sort of oddities, competent programmers would not
intentionally try to obscure their code by using constructs like the last one.

It seems to me that this discussion is going down the irrational path of "if it
exists in C it must be evil".  This doesn't help evaluating the pro and cons of
the proposal.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  12:55 PM

> I was worried more about the earlier proposals like:
>
>         f(x).all +:= 1;
>         f(x).all := itself + 1;

seems clear, ambiguous and illegal if ambiguous, otherwise not, can you say what
your concern is.

Both of these are equivalent to

          f(x).all := f(x).all + 1;

and should be illegal due to ambiguity under exactly the same circumances.

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

From: Randy Brukardt
Sent: Wednesday, November 18, 2009  1:02 PM

> I don't think there has been any mention of overloading resolution
> implications for the shorthand proposals, given that Ada allows the
> lhs of an assignment to be ambiguous.

Yes, I was just thinking about that. In our compiler, the resolution of ":=" is
handled by a special, rather lengthy routine because there is no type at all to
resolve to (and our resolver depends on having an expected type, which could be
"any type"). We'd have to have a similar routine, but it would be far more
complex than simple type matching as the types in question would depend on the
operators that are visible. Sounds like a nightmare to me in our compiler (for
that reason, I doubt that I'd ever try to implement such shorthands).

I realize that other compilers use different resolution schemes that might make
that easy to implement (Robert claims 2 hours in GNAT, that's probably accurate
for the code generation portion of it, but the resolution would be a lot more
complex).

That brings up another question: I've been assuming that "X +:= Y" is exactly
shorthand for "X := X + Y", meaning that user-defined "+" participate. The only
way that I can think of that would make this easy to implement is to allow it
for only predefined operators, but that makes it a form of re-emergence (and in
non-generic code at that). I don't think we want any more of those.

P.S. I'm much more interested in the 'Inc/'Dec proposal.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  1:12 PM

> Yes, I was just thinking about that. In our compiler, the resolution of ":="
> is handled by a special, rather lengthy routine because there is no
> type at all to resolve to (and our resolver depends on having an
> expected type, which could be "any type"). We'd have to have a similar
> routine, but it would be far more complex than simple type matching as
> the types in question would depend on the operators that are visible.
> Sounds like a nightmare to me in our compiler (for that reason, I
> doubt that I'd ever try to implement such shorthands).

Randy, your compiler seems to have an undue number of implementation nightmares,
I don't think we can be unduly influenced by this.

> I realize that other compilers use different resolution schemes that
> might make that easy to implement (Robert claims 2 hours in GNAT,
> that's probably accurate for the code generation portion of it, but
> the resolution would be a lot more complex).

We don't see any difficulty for +:=. Perhaps "it" would be more trouble, but
frankly I don't see the general "it" proposal flying anyway.

> That brings up another question: I've been assuming that "X +:= Y" is
> exactly shorthand for "X := X + Y", meaning that user-defined "+"
> participate. The only way that I can think of that would make this
> easy to implement.

Again, I don't think we should let our thinking be influenced by the degree of
difficulty of implementation in Randy's compiler.

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

From: Dan Eilers
Sent: Wednesday, November 18, 2009  1:20 PM

> > I was worried more about the earlier proposals like:
> >
> >         f(x).all +:= 1;
> >         f(x).all := itself + 1;
>
> seems clear, ambiguous and illegal if ambiguous, otherwise not, can
> you say what your concern is.
>
> Both of these are equivalent to
>
>           f(x).all := f(x).all + 1;
>
> and should be illegal due to ambiguity under exactly the same
> circumances.

My conern is that in

            f(x).all := f(x).all + 1;

the lhs f can resolve to a different f than the rhs f, while being legal and
unambiguous.

When written as

            f(x).all +:= 1;

it would be very strange for the implicit rhs f to resolve differently than the
lhs f.  So I don't think you can have a simple equivalence, as proposed.

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  1:22 PM

> Both of these are equivalent to
>
>           f(x).all := f(x).all + 1;

I'm pretty sure that's not what we want!

We do not want to evaluate the left-hand side twice.

And if it's a textual equivalence like that, it means that names in the
left-hand side could resolve to different declarations in the "phantom" copy of
the left-hand side.  That's weird, plus it would necessarily imply evaluating
twice.

I think Dan has a legitimate concern about the overloading rules.  I think there
are probably solutions, but I won't think about or discuss them until Ed's straw
poll is over -- maybe we'll end up dropping the idea.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  1:27 PM

...
> it would be very strange for the implicit rhs f to resolve differently
> than the lhs f.  So I don't think you can have a simple equivalence,
> as proposed.

Indeed, I understand the point, I don't think there is any significant
resolution problem, but it shows that it is not an equivalence, even if no side
effects are involved. I think everyone assumes your interpretation, but it does
need to be stated.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  1:30 PM

> We do not want to evaluate the left-hand side twice.

Right, I guess I was using equivalent in the RM sense (i.e. vaguely similar but
different from :-) :-)

> And if it's a textual equivalence like that, it means that names in
> the left-hand side could resolve to different declarations in the
> "phantom" copy of the left-hand side.  That's weird, plus it would
> necessarily imply evaluating twice.

Absolutely

> I think Dan has a legitimate concern about the overloading rules.

I agree

> I think
> there are probably solutions, but I won't think about or discuss them
> until Ed's straw poll is over -- maybe we'll end up dropping the idea.

Seems like a simple problem to solve, and I think we know what we want here, but
no need to study in detail.

Note that Algol-68 did not have overloading by result, so the situation was
straightforward there.

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

From: Randy Brukardt
Sent: Wednesday, November 18, 2009  1:34 PM

...
> > That brings up another question: I've been assuming that "X +:= Y"
> > is exactly shorthand for "X := X + Y", meaning that user-defined "+"
> > participate. The only way that I can think of that would make this
> > easy to implement.
>
> Again, I don't think we should let our thinking be influenced by the
> degree of difficulty of implementation in Randy's compiler.

You misunderstand; maybe you were mislead by the previous discussion. I was
talking about *all* compilers. I don't think that there is sufficient context in
<obj> +:= <expr> to do general case resolution in any sane way. And I wanted to
confirm the intended semantics to ensure that I was thinking about the right
thing (and also that you are thinking about the same thing as I was).

The experience of the ARG is that the implementation of resolution algorithms
vary widely. Whether one compiler can implement it "easily" has no bearing on
whether that is true for other compilers. (And the same goes in reverse, of
course. I was just giving a data point.)

So I repeat, is the intended semantics that user-defined operators participate
in "+:=" (which of course implies visibility participates as well)? Do operators
with operands of different types participate, such as the "&" operators found in
Ada.Strings.Unbounded? Is

          My_Unbounded_String &:= "more text";

intended to work??

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  1:42 PM

> So I repeat, is the intended semantics that user-defined operators
> participate in "+:=" (which of course implies visibility participates
> as well)?

My answer would be, yes if simple, no if not, since all I really want is
predefined + and -

> Do operators with operands of different types participate, such as the
> "&" operators found in Ada.Strings.Unbounded? Is
>
>           My_Unbounded_String &:= "more text";
>
> intended to work??

My answer would be yes if simple, no it not, since all I really want is
predefined + and -

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

From: Tucker Taft
Sent: Wednesday, November 18, 2009  1:39 PM

I agree with Ed that we should stop discussing this and just do the straw poll.

[Editor's note: Straw poll results filed at the end, so as to be altogether.]

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

From: Edmond Schonberg
Sent: Wednesday, November 18, 2009  9:31 AM

> I agree with Ed that we should stop discussing this and just do the straw
> poll.

Dan's latest comment is an important part of the discussion. If

     F(x). all :=  F(x).all + 1;

is not semantically equivalent to

     F(X).all +:=  1;

(easy to concoct an example where the two F's are different) then the  op:=
proposal is problematic, unless we have a different resolution rule for it, and
it has to be simple to state.  I don't have one at hand, unless we forbid
user-defined operators.

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

From: Gary Dismukes
Sent: Wednesday, November 18, 2009  9:31 AM

> ... I was
> talking about *all* compilers. I don't think that there is sufficient
> context in <obj> +:= <expr> to do general case resolution in any sane way.
> And I wanted to confirm the intended semantics to ensure that I was
> thinking about the right thing (and also that you are thinking about
> the same thing as I was).

One way to go would be to define the target object as a complete context, so it
would need to be unambiguous to begin with, and then resolve the right-hand
separately in terms of "<target-type> + <expr>".  This is different than normal
assignment resolution, but that's unavoidable I think.

...
> So I repeat, is the intended semantics that user-defined operators
> participate in "+:=" (which of course implies visibility participates
> as well)? Do operators with operands of different types participate,
> such as the "&" operators found in Ada.Strings.Unbounded? Is
>
>           My_Unbounded_String &:= "more text";
>
> intended to work??

If we went this way, then I think yes, user-defined operators should
participate.  As you say, we wouldn't want reemergence here.  And I would allow
mixed-type operators like "&", though I could also live without them (but I
don't see any particular difficulty with those).

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

From: Edmond Schonberg
Sent: Wednesday, November 18, 2009  2:20 PM

> One way to go would be to define the target object as a complete
> context, so it would need to be unambiguous to begin with, and then
> resolve the right-hand separately in terms of "<target-type> +
> <expr>".  This is different than normal assignment resolution, but
> that's unavoidable I think.

That works, it's a simple rule, and allows user-defined operators.
with this rule my choice is a).

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  2:49 PM

> Note that Algol-68 did not have overloading by result, so the
> situation was straightforward there.

Does any language (besides Ada)?

I think it's an important feature.

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  2:54 PM

Not that I know of, I agree it's important, but it does add a lot of
complications :-)

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

From: Gary Dismukes
Sent: Wednesday, November 18, 2009  3:37 PM

> > One way to go would be to define the target object as a complete
> > context, so it would need to be unambiguous to begin with, and then
> > resolve the right-hand separately in terms of "<target-type> +
> > <expr>".  This is different than normal assignment resolution, but
> > that's unavoidable I think.
>
> That works, it's a simple rule, and allows user-defined operators.
> with this rule my choice is a).

Actually, it would be better to define the target as expecting any type rather
than being a complete context (for one thing, a statement is already defined to
be a complete context, and those are normally supposed to be top-level things).

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  4:14 PM

> Actually, it would be better to define the target as expecting any
> type rather than being a complete context

Does it make any difference to what's legal?

Or are you just saying it's more aesthetically pleasing to say "expected type is
any type"?  If so, I guess I'd agree.

>... (for one thing, a statement is
> already defined to be a complete context, and those are normally
>supposed to be top-level things).

Complete contexts can be nested.  A statement is a complete context, and
statements can be nested.  A case very similar to the one here is that a case
expression is a complete context.

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

From: Gary Dismukes
Sent: Wednesday, November 18, 2009  5:36 PM

> Does it make any difference to what's legal?
>
> Or are you just saying it's more aesthetically pleasing to say
> "expected type is any type"?  If so, I guess I'd agree.

I don't think it makes any difference as to what's legal, I guess it just seems
more natural.  It feels more like a context like a type conversion argument,
whereas I tend to think of complete contexts as something more at the level of a
declaration or statement rather than a name or expression that's part of a
larger construct.

> >... (for one thing, a statement is
> > already defined to be a complete context, and those are normally
> >supposed to be top-level things).
>
> Complete contexts can be nested.  A statement is a complete context,
> and statements can be nested.  A case very similar to the one here is
> that a case expression is a complete context.

True enough, "top-level" wasn't quite the right phrasing.  Somehow it feels
funny calling the left-hand side a complete context when the assignment
statement itself is one.

Anyway, it's kind of academic to discuss things at this level until we decide
whether this feature is actually going to go in...

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

From: Edmond Schonberg
Sent: Wednesday, November 18, 2009  12:34 PM

I have the sense that this discussion has exhausted the topic. On one  hand
there is a simple proposal for a useful syntactic abbreviation,   first seen 40
years ago in Algol68, and since then adopted by several  languages and in wide
use. On the other hand there are several   ingenious and diverse proposals for
getting similar functionality with syntactic inventions that lack the
conciseness and universal familiarity of the original. I would like to have a
straw poll to estimate the likelihood that some concrete proposal will emerge
from this. Could each participant in this discussion choose one (only one) of
the following:

a)  Binary assignment operators   op:=   for all binary operators.

b)  A different syntax (any one of those suggested so far, no need to
specify)

c) Leave this out of the amendment.

In terms of the amendment, this is obviously minuscule.  For those looking for
rich and complex technical  issues to discuss, let me  suggest Tuck's proposal
for subpools.   New ideas in storage  management are immensely more critical
than syntactic shortcuts :-)!

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

From: Robert Dewar
Sent: Wednesday, November 18, 2009  12:57 PM

I choose a)

> In terms of the amendment, this is obviously minuscule.  For those
> looking for rich and complex technical  issues to discuss, let me
> suggest Tuck's proposal for subpools.   New ideas in storage
> management are immensely more critical than syntactic shortcuts :-)!

And immensely more fruitful if your objective is to limit the complexity of the
amendment :-)

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

From: Bob Duff
Sent: Wednesday, November 18, 2009  12:59 PM

Am I allowed to abstain?

If you insist that I vote, I guess I have a mild preference for c) at this
point.

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

From: Randy Brukardt
Sent: Wednesday, November 18, 2009  1:05 PM

> I have the sense that this discussion has exhausted the topic.

I agree, although Tucker's attribute suggestion might be a useful compromise.

>Vote:

(c) followed by (b) [The 'Inc attribute].

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

From: Tucker Taft
Sent: Wednesday, November 18, 2009  1:18 PM

First choice: leave it out
Second choice: X'Incr/Decr[(By => expression)];

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

From: Dan Eilers
Sent: Wednesday, November 18, 2009  1:20 PM

my preference is c) although some form of b) may be acceptable.

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

From: Edmond Schonberg
Sent: Wednesday, November 18, 2009  2:20 PM

> One way to go would be to define the target object as a complete
> context, so it would need to be unambiguous to begin with, and then
> resolve the right-hand separately in terms of "<target-type> +
> <expr>".  This is different than normal assignment resolution, but
> that's unavoidable I think.

That works, it's a simple rule, and allows user-defined operators.
with this rule my choice is a).

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

From: Pascal Leroy
Sent: Wednesday, November 18, 2009  3:03 PM

Me too, with c) as a second choice.

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

From: Arnaud Charlet
Sent: Wednesday, November 18, 2009  3:39 AM

Same for me.

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

From: Brad Moore
Sent: Wednesday, November 18, 2009  9:44 PM

First choice: => b) (X'Incr/Dec[By => expression)]; Second choice: => c) leave
it out

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

From: Steve Baird
Sent: Thursday, November 19, 2009  2:05 AM

I vote for a), with some version of the b) as my second choice.

I don't care about users having to write
    X := X + 1;

I want to avoid textually repeating (and dynamically reevaluating) a long and/or
complex name without having to resort to a declare block and a rename.

 > I think that
 > choosing a familiar syntax in this case is actually a positive move:
 > there is no point in looking different when there is a convergence of  > syntactic conventions among leading languages.

I agree with Ed. I also agree with Tuck that Type_Name'Incr seems more Ada-like,
but I think that Ed's argument is stronger. It's a close call.

Incidentally, if we went with Object_Name'Incr, then there might be a little bit
of complexity associated with renames thereof, as in

    procedure Ren renames Function_Call.Access_Discriminant.all'Inc

If the result type of the function requires finalization and the access
discriminant denotes a coextension, then we might need to treat this as a
lifetime-extending rename like the constructs discussed in AI05-0066. This might
fall out from the existing wording, but I think it would still be a bit of extra
work for implementers.

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

From: Jean-Pierre Rosen
Sent: Thursday, November 19, 2009  4:18 AM

After carefully studying all previous mail, here is my position, FWIW:

1) It is not a really important feature
2) It matters only for complicated names in the lhs; personnally, when I
   encounter such names, I prefer to use a renaming anyway, just to remember
   what it means and why it is being accessed this way.
3) which explains why I never felt the need for that feature

BUT

In think it is good PR to add it to the language, and I think Ada needs good PR
much more than new features.

Therefore, I'm in favor of it, provided it uses the regular "+:="
syntax; everything else would be bad PR.

Should the space be allowed? I don't feel strongly either side, although  I
wouldn't like to see things like:

A+ := 1;

But there are so many ways of writing misleading things...

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

From: Jean-Pierre Rosen
Sent: Thursday, November 19, 2009  4:39 AM

I can live with a) or c). Opposed to b) (itself, <-).

I think 'Incr and 'Decr should be separated from b), as it is a different
proposal that could be accepted in addition to a). Can live with it too.

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

From: Dan Eilers
Sent: Thursday, November 19, 2009  10:44 AM

Without trying to restart discussions on this topic, here are two additional
proposals for the record that don't involve any new symbols or keywords, yet are
concise, general enough to support short-circuit operations, and not susceptible
to single-character typos.

        x do + 1;    -- interpreted as do "+ 1" to x

        out x + 1;   -- interpreted as x is updated in "x + 1".

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

From: Robert Dewar
Sent: Thursday, November 19, 2009  10:53 AM

Well you *are* trying to restart discussion! And discussion is closed for now!
Till the straw poll is complete.

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

From: Edmond Schonberg
Sent: Thursday, November 19, 2009  11:11 AM

Well, I take it that Dan's comment is a vote for options b) :  some other
syntactic innovation.

Even though not all ARG members have expressed their opinions, it is clear that
there is no consensus. In fact, not even within individual voters, who could not
refrain from listing two options!  The tally so far is:

a)  Seven votes

b)  Four votes.

c)  Seven votes, often mentioned as a second choice.

Unless someone is prepared to write a detailed AI,  the issue is dead.

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

From: Erhard Ploedereder
Sent: Saturday, November 21, 2009  7:08 PM

Given the choices, I opt for c) leave it out.
My choice would have been to provide +:= and -:=, nothing else.

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


Questions? Ask the ACAA Technical Agent