Overloading assignment operator


(Don Wills) #1

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

Don Wills


(Don Wills) #2

Silvan,

Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse.

FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does:

var amount = Number(left: 6, right: 2);
var result = Number(left: 9, right: 2);
amount <- 3.9;
amount += 1;
result <- amount * 4;
print(result)

Note that <- is the assignment operator. I am sure all would agree that = is superior in this situation. Such code would be far more readable and the Number values would act just like and interoperate with Float and Int in all regards *except* that currently the = operator is not available for assignment.

Don Wills

PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner mentioned to me is inferior to the kind of support for fixed decimal arithmetic that I believe would help make Swift superior to C# for business applications.

···

On Dec 6, 2015, at 6:58 AM, Silvan Mosberger <kametrixom@icloud.com> wrote:

Hi Don

I think this is a terrible idea! Imagine what you’d be able to do with that:

let x : String = 3

This would lead to the same problems already discussed with implicit initialisers: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000531.html, just worse. Also assignment is something more fundamental than other operators, I doubt it’s even possible to do that.

On 06 Dec 2015, at 14:44, Don Wills via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

Don Wills
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(John McCall) #3

In your specific case, I think Alex Lew is completely correct: you really don’t want a ton of overloaded operators, you just want your decimal type to be literal-convertible.

But to answer the question more generally, no, I can’t foresee us ever allowing the overloading of =, no. = always means simple initialization/assignment in Swift; that is, it always simply propagates values around. That’s a very fundamental language concept to mess around with.

The way to fix your problem in a less ad hoc way is to allow user-defined implicit conversions, which is something we’ve talked about already in a different thread. What I said there was that it will require a lot of very careful language/type-checker design work. Here, I’d like to identity another problem: the behavior of implicit conversions can be very confusing for non-experts to reason about, and in the context of a language with a fair amount of other subtle behaviors (e.g. due to overloading), that’s a very dangerous thing to bring in. Explicit type coercions are much easier for non-experts to reason about.

John.

···

On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <swift-evolution@swift.org> wrote:

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?


(Alex Lew) #4

Don, have you considered making your Number type FloatLiteralConvertible?
This would allow you not just to *let number: Number = 4.9*, but also pass
in 4.9 to a function that expected a *Number*. It would not let you set
Number variables to be equal to other variables of type Float, it seems
your main use case here is literals anyway.

http://swiftdoc.org/v2.0/protocol/FloatLiteralConvertible/

···

On Sun, Dec 6, 2015 at 9:26 AM, Don Wills via swift-evolution < swift-evolution@swift.org> wrote:

Silvan,

Yes, I understand the concern you raise. I too have held that general
opinion of overloading operators in other languages for many years. That
said, overloading arithmetic and other operators causes the same
opportunity for abuse. For example, overloading + for integers to do
something different (like rounding instead of truncation) would make
maintenance of existing programs into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't
see how adding support for = makes things any worse.

FYI, the reason for my suggestion is to add support for fixed decimal
arithmetic just like that available in COBOL. Yeh I can hear the groans
now. However, for business applications, fixed decimal arithmetic is a
basic feature that has been tossed away in new languages by language
designers who don't actually labor in the trenches. I've built a simple
class to do just that - here is some sample code that uses my Number class
that gives an idea of what the code does:

var amount = Number(left: 6, right: 2);
var result = Number(left: 9, right: 2);
amount <- 3.9;
amount += 1;
result <- amount * 4;
print(result)

Note that <- is the assignment operator. I am sure all would agree that =
is superior in this situation. Such code would be far more readable and
the Number values would act just like and interoperate with Float and Int
in all regards *except* that currently the = operator is not available for
assignment.

Don Wills

PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner
mentioned to me is inferior to the kind of support for fixed decimal
arithmetic that I believe would help make Swift superior to C# for business
applications.

On Dec 6, 2015, at 6:58 AM, Silvan Mosberger < kametrixom@icloud.com> > wrote:

Hi Don

I think this is a terrible idea! Imagine what you’d be able to do with
that:

let x : String = 3

This would lead to the same problems already discussed with implicit
initialisers:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000531.html,
just worse. Also assignment is something more fundamental than other
operators, I doubt it’s even possible to do that.

On 06 Dec 2015, at 14:44, Don Wills via swift-evolution < > swift-evolution@swift.org> wrote:

The ability to overload operators is very useful. However, that utility
is diminished without the ability to overload the simple assignment
operator ( = ). I vaguely recall reading somewhere that there is a reason
for this having to do with syntax ambiguity. Can this problem be solved so
that = can be overloaded?

Don Wills
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Untracked with Trackbuster <https://trackbuster.com/?sig>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(ilya) #5

Yes, I meant for the email to go to the list.

Nope, that doesn't work because of my comment above. That's the change

to Swift I am hoping will be adopted for 3.0.

Did you try this? The idea is to write a function for multiplying a Number
and an Int, so the rhs will create a Number which will then be set to the
variable. It should work actually.

···

On Mon, Dec 7, 2015 at 00:47 Don Wills <don.wills@portablesoftware.com> wrote:

Hello Ilya,

On Dec 6, 2015, at 1:09 PM, ilya <ilya.nikokoshev@gmail.com> wrote:

On Sun, Dec 6, 2015 at 5:26 PM, Don Wills via swift-evolution < > swift-evolution@swift.org> wrote:

Silvan,

Yes, I understand the concern you raise. I too have held that general
opinion of overloading operators in other languages for many years. That
said, overloading arithmetic and other operators causes the same
opportunity for abuse.

For example, overloading + for integers to do something different (like

rounding instead of truncation) would make maintenance of existing programs
into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't
see how adding support for = makes things any worse.

This is not really the same. You only use + explicitely, but the compiler
must insert some assigments automatically, for example by copying when the
function closes over some variables. It must know exactly what the
semantics in this case is to be able to compile correct program.

My example wasn't the best. IMO, there is almost no conceptual difference
between "amount = 5.5;" and "amount += 5.5;". The second example works
(that is += can be overloaded) where the first example is not allowed
because when I try to define the "func = (...) {...}" overload
implementation, the compiler squawks.

FYI, the reason for my suggestion is to add support for fixed decimal

arithmetic just like that available in COBOL. Yeh I can hear the groans
now.

I'm with you.

However, for business applications, fixed decimal arithmetic is a basic
feature that has been tossed away in new languages by language designers
who don't actually labor in the trenches.

I didn't look into the new Foundation, but doesn't it contain
NSDecimalNumber?

I've built a simple class to do just that - here is some sample code that

uses my Number class that gives an idea of what the code does:

var amount = Number(left: 6, right: 2);
var result = Number(left: 9, right: 2);
amount <- 3.9;
amount += 1;
result <- amount * 4;
print(result)

I'm not sure why you feel the need to overload = in this example. If
Number * Int -> Number is defined, you can just use

result = amount * 4

Nope, that doesn't work because of my comment above. That's the change to
Swift I am hoping will be adopted for 3.0.

Did you mean to not post your email to me only? I haven't figured out the
protocol for this email list yet.

Don Wills


(Don Wills) #6

John,

···

On Dec 6, 2015, at 10:54 PM, John McCall <rjmccall@apple.com> wrote:

On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <swift-evolution@swift.org> wrote:

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

In your specific case, I think Alex Lew is completely correct: you really don’t want a ton of overloaded operators, you just want your decimal type to be literal-convertible.

But to answer the question more generally, no, I can’t foresee us ever allowing the overloading of =, no. = always means simple initialization/assignment in Swift; that is, it always simply propagates values around. That’s a very fundamental language concept to mess around with.

I guess I missed the subtlety that in Swift the statement "x = y;" is fundamentally different than "x += y;". That surprises me. And it fails one of the basic principles that I've always applied to software design: The Principle of Least Astonishment.

Thanks for your response, even though it is quite disheartening to me. As I get to know the nuances of Swift, I'm starting to think that moving to Swift might be too big of a stretch for my programming staff.

Don Wills


(Matthew Johnson) #7

Here, I’d like to identity another problem: the behavior of implicit conversions can be very confusing for non-experts to reason about, and in the context of a language with a fair amount of other subtle behaviors (e.g. due to overloading), that’s a very dangerous thing to bring in. Explicit type coercions are much easier for non-experts to reason about.

+1 to this. I am very skeptical that the benefit of implicit conversions are worth the complexity and potential for confusion, except where a natural subtype relationship exists like Chris has mentioned in relation to numerics.


#8

I think that his number assignment (via `<~`) depends on the current state of `amount`, and that using FloatLiteralConvertible does not provide enough information at the call site (since the current value is not available in the initializer).

Stephen

···

On Dec 6, 2015, at 1:43 PM, Alex Lew via swift-evolution <swift-evolution@swift.org> wrote:

Don, have you considered making your Number type FloatLiteralConvertible? This would allow you not just to let number: Number = 4.9, but also pass in 4.9 to a function that expected a Number. It would not let you set Number variables to be equal to other variables of type Float, it seems your main use case here is literals anyway.

http://swiftdoc.org/v2.0/protocol/FloatLiteralConvertible/

On Sun, Dec 6, 2015 at 9:26 AM, Don Wills via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Silvan,

Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse. For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse.

FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now. However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches. I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does:

var amount = Number(left: 6, right: 2);
var result = Number(left: 9, right: 2);
amount <- 3.9;
amount += 1;
result <- amount * 4;
print(result)

Note that <- is the assignment operator. I am sure all would agree that = is superior in this situation. Such code would be far more readable and the Number values would act just like and interoperate with Float and Int in all regards *except* that currently the = operator is not available for assignment.

Don Wills

PS. FWIW, the IEEE 754-2008 d128 alternative that Chris Lattner mentioned to me is inferior to the kind of support for fixed decimal arithmetic that I believe would help make Swift superior to C# for business applications.

On Dec 6, 2015, at 6:58 AM, Silvan Mosberger < kametrixom@icloud.com <mailto:kametrixom@icloud.com>> wrote:

Hi Don

I think this is a terrible idea! Imagine what you’d be able to do with that:

let x : String = 3

This would lead to the same problems already discussed with implicit initialisers: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000531.html, just worse. Also assignment is something more fundamental than other operators, I doubt it’s even possible to do that.

On 06 Dec 2015, at 14:44, Don Wills via swift-evolution < swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

Don Wills
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Untracked with Trackbuster <https://trackbuster.com/?sig>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Don Wills) #9

Hello Ilya,

Yes, I meant for the email to go to the list.

> Nope, that doesn't work because of my comment above. That's the change to Swift I am hoping will be adopted for 3.0.

Did you try this? The idea is to write a function for multiplying a Number and an Int, so the rhs will create a Number which will then be set to the variable. It should work actually.

Yes, I've written a class named Number with many "func <operator> ( ... ) { ... }" implementations for the various permutations of Number, Double and operators. They all work except for when <operator> is the equal sign.

Don

···

On Dec 6, 2015, at 3:05 PM, ilya <ilya.nikokoshev@gmail.com> wrote:

On Mon, Dec 7, 2015 at 00:47 Don Wills <don.wills@portablesoftware.com <mailto:don.wills@portablesoftware.com>> wrote:
Hello Ilya,

On Dec 6, 2015, at 1:09 PM, ilya <ilya.nikokoshev@gmail.com <mailto:ilya.nikokoshev@gmail.com>> wrote:

On Sun, Dec 6, 2015 at 5:26 PM, Don Wills via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Silvan,

Yes, I understand the concern you raise. I too have held that general opinion of overloading operators in other languages for many years. That said, overloading arithmetic and other operators causes the same opportunity for abuse.
For example, overloading + for integers to do something different (like rounding instead of truncation) would make maintenance of existing programs into a giant guessing game.

That said, once the cat is out of the bag to overload operators, I don't see how adding support for = makes things any worse.

This is not really the same. You only use + explicitely, but the compiler must insert some assigments automatically, for example by copying when the function closes over some variables. It must know exactly what the semantics in this case is to be able to compile correct program.

My example wasn't the best. IMO, there is almost no conceptual difference between "amount = 5.5;" and "amount += 5.5;". The second example works (that is += can be overloaded) where the first example is not allowed because when I try to define the "func = (...) {...}" overload implementation, the compiler squawks.

FYI, the reason for my suggestion is to add support for fixed decimal arithmetic just like that available in COBOL. Yeh I can hear the groans now.

I'm with you.

However, for business applications, fixed decimal arithmetic is a basic feature that has been tossed away in new languages by language designers who don't actually labor in the trenches.

I didn't look into the new Foundation, but doesn't it contain NSDecimalNumber?

I've built a simple class to do just that - here is some sample code that uses my Number class that gives an idea of what the code does:

var amount = Number(left: 6, right: 2);
var result = Number(left: 9, right: 2);
amount <- 3.9;
amount += 1;
result <- amount * 4;
print(result)

I'm not sure why you feel the need to overload = in this example. If Number * Int -> Number is defined, you can just use

result = amount * 4

Nope, that doesn't work because of my comment above. That's the change to Swift I am hoping will be adopted for 3.0.

Did you mean to not post your email to me only? I haven't figured out the protocol for this email list yet.

Don Wills


(John McCall) #10

John,

The ability to overload operators is very useful. However, that utility is diminished without the ability to overload the simple assignment operator ( = ). I vaguely recall reading somewhere that there is a reason for this having to do with syntax ambiguity. Can this problem be solved so that = can be overloaded?

In your specific case, I think Alex Lew is completely correct: you really don’t want a ton of overloaded operators, you just want your decimal type to be literal-convertible.

But to answer the question more generally, no, I can’t foresee us ever allowing the overloading of =, no. = always means simple initialization/assignment in Swift; that is, it always simply propagates values around. That’s a very fundamental language concept to mess around with.

I guess I missed the subtlety that in Swift the statement "x = y;" is fundamentally different than "x += y;". That surprises me.

It shouldn’t. I am not aware of any languages in which = (or its equivalent) is just a normal overloaded operator. Even in C++, (1) there are different formation rules for assignment operators, (2) assignment operators are often implicitly generated, (3) explicitly declared assignment operators can have subtle effects on formal language behavior, and (4) the resolution rules for assignment are different from the rules for other user-defined operators, even compound assignment.

Oh, and of course (5) the token “=" doesn’t mean assignment in the contexts where it actually means initialization, which is something that was actually confused earlier in this thread, and which is probably the single most common point of confusion among even quite knowledgeable C++ programmers — and which is, by and large, a problem that we’ve defined away in Swift by not introducing this kind of semantic confusion around the behavior of =.

And it fails one of the basic principles that I've always applied to software design: The Principle of Least Astonishment.

In fact, in my experience, programmers tend to be quite astonished by the behavior of overloaded assignment.

Again, the feature you actually need for all of your examples is literal convertibility, which already exists; please look into it before writing off the language.

John.

···

On Dec 6, 2015, at 10:17 PM, Don Wills <don.wills@portablesoftware.com> wrote:

On Dec 6, 2015, at 10:54 PM, John McCall <rjmccall@apple.com> wrote:

On Dec 6, 2015, at 5:44 AM, Don Wills via swift-evolution <swift-evolution@swift.org> wrote:

Thanks for your response, even though it is quite disheartening to me. As I get to know the nuances of Swift, I'm starting to think that moving to Swift might be too big of a stretch for my programming staff.

Don Wills


(Don Wills) #11

Thanks to all who replied. I apologize that my responses were disjoint - my spam checker delayed a couple of the messages until this morning.

To those who suggested literal convertibles, I believe Stephen is correct in that it is insufficient to accomplish the semantics that I want with the syntax I had hoped for. It is about more than just initialization. I'll probably just use ":=" as the assignment operator. Not optimal, but it works.

Don

···

On Dec 6, 2015, at 11:59 AM, Stephen Celis <stephen.celis@gmail.com> wrote:

I think that his number assignment (via `<~`) depends on the current state of `amount`, and that using FloatLiteralConvertible does not provide enough information at the call site (since the current value is not available in the initializer).


#12

For what it's worth, you can accomplish a lot of assignment operator
overload behavior via property get/set/willSet/didSet (similar to how Ruby
methods suffixed with "=" are dispatched via dot notation), though it would
require you to design your interface so that "=" is called on a property.

Stephen

···

On Mon, Dec 7, 2015 at 9:15 AM, Don Wills via swift-evolution < swift-evolution@swift.org> wrote:

Thanks to all who replied. I apologize that my responses were disjoint -
my spam checker delayed a couple of the messages until this morning.

To those who suggested literal convertibles, I believe Stephen is correct
in that it is insufficient to accomplish the semantics that I want with the
syntax I had hoped for. It is about more than just initialization. I'll
probably just use ":=" as the assignment operator. Not optimal, but it
works.

Don

> On Dec 6, 2015, at 11:59 AM, Stephen Celis <stephen.celis@gmail.com> > wrote:
>
> I think that his number assignment (via `<~`) depends on the current
state of `amount`, and that using FloatLiteralConvertible does not provide
enough information at the call site (since the current value is not
available in the initializer).

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution