From: Robert A Duff on
stefan-lucks(a)see-the.signature writes:

> On Sun, 22 Nov 2009, Robert A Duff wrote:
>
>> Ada uses the term "assignment" to refer to both "initial assignment /
>> initialization" and "assignment_statement / overwriting".
>> I'd prefer to use different symbols for the two.
>> We're not going to change Ada in that regard, for compatibility reasons,
>> but I'm thinking in my hobby language design to use the term "assignment"
>> for the initial one, and "reassignment" for the subsequent overwriting
>> one, and use different symbols for the two.
>>
>> So, for a limited type, "assignment" is legal, "reassignment" is not.
>
> Distinguishing the two different operations which are written as ":=" in
> Ada by using different words and even different symbols would make a lot of
> sense.

I definitely want to use different symbols as well as different words.
But I'm not sure what symbols to choose. Maybe := and :== .

I want to allow:

X : Integer;

if ... then
X := 0; -- initialize (what I want to call "assign")
else
X := 1; -- initialize (what I want to call "assign")
end if;

while ... loop
X :== X + 1; -- overwriting (what I want to call "reassign")
...
end loop;

> But it is quite a standard notion to write "assignment" for overwriting
> the current value of a variable by a new value.

Well, the term is used in many non-functional languages for both cases:
overwriting junk-bits with a value, and overwriting a
previously-assigned value with a value. This is presumably because
in those languages, there's no important difference between the two.

In functional languages, the term "single assignment" is sometimes used,
which means you can initialize a variable, but you can never overwrite.

>... This notion is widely
> used, much beyond Ada. You would likely confuse people by calling that
> operation a "reassignment" and using "assignment" for anther kind of
> operation. Please don't do that!

Well, the word "reassignment" contains the word "assignment" -- it means
"to assign again". I don't see why that would be confusing.

Ada (to keep this slightly on topic ;-)) of course uses "assignment"
for both kinds: initialization and assignment_statement. I find
that confusing, because you'd think "assignment_statement" is the (only)
thing that does "assignment".

> Better use "assignment" for the overwriting operation, and another word
> (such as "initial assignment", "constructive assignment", "inisignment",
> ... a native English speaker might find better words) for the type of
> assignment that does not overwrite an existing value, and which is allowed
> for limited types.

Thanks for the advice, but I'm not sure I'm convinced to take it.

If we agree that there are two different kinds of things called
"assignment" in common languages, I don't see why one should deserve the
term "assignment" in preference to the other...

- Bob
From: Robert A Duff on
"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> writes:

> The word assignment for most people is associated with state change,
> assuming that there was some state before. So
>
> X : T := F (Y);
>
> looks equivalent to
>
> X : T;
> begin
> X := F (Y);
>
> But they are not.

Right. I think they should be equivalent. My solution is to use
two different symbols for (initial) assignment and (subsequent)
reassignment.

>... I would prefer proper constructors, e.g.
>
> X : T (Y); -- Y is a constraint of T, parameter of the constructor
>
> I don't like functions returning limited objects.

I know you don't, but I don't understand why.

Using named functions as constructors has a big advantage -- you can
have more than one, and you can give them meaningful names.

For example:

X : Sequence := Empty_Seq;
Y : Sequence := Singleton_Seq (Item => 123);
Z : Sequence := Make_Sequence (Length => 123);

With discriminants, what does the 123 mean? You have to pick one.

> But there also are two other forms of standard assignments. Depending on
> whether the left part is available:
>
> procedure ":=" (Left : in out T; Right : T);
>
> and
>
> function ":=" (Right : T) return T;
>
> Ada uses the second form, but obviously there are important cases where the
> first form is preferable (and conversely).
>
> And further, there are three variants per each concerning dispatch:
>
> procedure ":=" (Left : in out T; Right : T); -- Full MD
> procedure ":=" (Left : in out T; Right : T'Class); -- Target-controlled
> procedure ":=" (Left : in out T'Class; Right : T); -- Source-controlled
>
> It would be difficult to sort this out! (:-))

Yeah, I'm not sure what the right answer is.

- Bob
From: (see below) on
On 30/11/2009 20:36, in article wcc8wdn697e.fsf(a)shell01.TheWorld.com,
"Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote:

> stefan-lucks(a)see-the.signature writes:

>> Distinguishing the two different operations which are written as ":=" in
>> Ada by using different words and even different symbols would make a lot of
>> sense.

> I definitely want to use different symbols as well as different words.
> But I'm not sure what symbols to choose. Maybe := and :== .
>
> I want to allow:
>
> X : Integer;
>
> if ... then
> X := 0; -- initialize (what I want to call "assign")
> else
> X := 1; -- initialize (what I want to call "assign")
> end if;
>
> while ... loop
> X :== X + 1; -- overwriting (what I want to call "reassign")
> ...
> end loop;

What is wrong with the terms "initialize" and "assign", respectively?

X : Integer initially if ... then 0 else 1 end if;
Y : Integer constant if ... then 1 else 2 end if;

while ... loop
X := X + Y; -- assign
...
end loop;

--
Bill Findlay
<surname><forename> chez blueyonder.co.uk


From: Dmitry A. Kazakov on
On Mon, 30 Nov 2009 15:43:21 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> writes:
>
>> The word assignment for most people is associated with state change,
>> assuming that there was some state before. So
>>
>> X : T := F (Y);
>>
>> looks equivalent to
>>
>> X : T;
>> begin
>> X := F (Y);
>>
>> But they are not.
>
> Right. I think they should be equivalent. My solution is to use
> two different symbols for (initial) assignment and (subsequent)
> reassignment.

But they cannot be, otherwise the semantics of ":=" would depend on the
things done before:

X : T;
begin
X := F (Y); -- Initialization

X : T;
begin
X := Z;
X := F (Y); -- [Re]assignment

This is unacceptable, because it is untyped. The semantics of ":=" must be
solely defined by the types and, maybe, be the context (declarative vs.
imperative (as it is now). I don't like even the second part.

>>... I would prefer proper constructors, e.g.
>>
>> X : T (Y); -- Y is a constraint of T, parameter of the constructor
>>
>> I don't like functions returning limited objects.
>
> I know you don't, but I don't understand why.

Because they cannot return anything, so a "return statement" is invented
together with an infinite chain of other unholy things bending and twisting
otherwise clear and established notions.

> Using named functions as constructors has a big advantage -- you can
> have more than one, and you can give them meaningful names.
>
> For example:
>
> X : Sequence := Empty_Seq;
> Y : Sequence := Singleton_Seq (Item => 123);
> Z : Sequence := Make_Sequence (Length => 123);
>
> With discriminants, what does the 123 mean? You have to pick one.

No problem:

X : Sequence;
Y : Sequence (Item => 123);
Z : Sequence (Length => 123);

In my imaginary world public discriminant (as well as a public record
component) is only an interface, therefore it is no problem for a type have
any collection of public discriminant sets. They are just like other
operations, you could overload them if necessary.

>> But there also are two other forms of standard assignments. Depending on
>> whether the left part is available:
>>
>> procedure ":=" (Left : in out T; Right : T);
>>
>> and
>>
>> function ":=" (Right : T) return T;
>>
>> Ada uses the second form, but obviously there are important cases where the
>> first form is preferable (and conversely).
>>
>> And further, there are three variants per each concerning dispatch:
>>
>> procedure ":=" (Left : in out T; Right : T); -- Full MD
>> procedure ":=" (Left : in out T; Right : T'Class); -- Target-controlled
>> procedure ":=" (Left : in out T'Class; Right : T); -- Source-controlled
>>
>> It would be difficult to sort this out! (:-))
>
> Yeah, I'm not sure what the right answer is.

I think that assignment should be considered a plain primitive procedure
with no special treatment. Initialization has in my view nothing to do with
it. The language should visually separate both.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: stefan-lucks on
On Tue, 1 Dec 2009, Dmitry A. Kazakov wrote:

> On Mon, 30 Nov 2009 15:43:21 -0500, Robert A Duff wrote:

> > Right. I think they should be equivalent. My solution is to use
> > two different symbols for (initial) assignment and (subsequent)
> > reassignment.
>
> But they cannot be, otherwise the semantics of ":=" would depend on the
> things done before:
>
> X : T;
> begin
> X := F (Y); -- Initialization

No, at this point of time, X has been initialised to *some* value, even if
the value itself is undefined. So this is just a proper assignment.

> X : T;
> begin
> X := Z;
> X := F (Y); -- [Re]assignment

That is a proper assignment, as well. The only difference is that we
can be sure the before-assignment value of X is defined (assuming the
value of Z is a defined one).

An initialisation would be

X : T ::= F(Y);
begin
...

But you are right, Dmitry, nobody would not want to distinguish an
assignment to overwrite a potentially undefined value from an assignment
ovwerwriting a previously defined value.

--
------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------
Stefan dot Lucks at uni minus weimar dot de
------ I love the taste of Cryptanalysis in the morning! ------