Mutability inference


(Darko Damjanovic) #1

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
  print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss


(David Smith) #2

One tricky thing with languages like this (javascript, for example) is that it becomes easy to accidentally introduce a new variable rather than refer to an existing one.

  David

···

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
  print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

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


(Mathieu Godart) #3

Interesting idea. I like to be able to be lazy! :blush:

But I agree with David. So, we could imagine a new keyword, like "varlet" or "autovar", or whatever to avoid confusion between declaration and assignment... But this would impact drastically the readability. The compiler would know, but not the human reader. And this loss in readability would be very impactful, imho. The mutability character carries a lot of information.

If you want to be lazy about it, what about letting the compiler advice you? You could define every new variable as "var", without thinking about it. And after you completed the implementation of the related scope, see what the compiler tells you. And just apply its advice.

Wouldn't that be sufficient?

Mathieu Godart

PS : This is my first post on this mailing list. So, hello the Swift community!

···

Le 24 févr. 2016 à 08:10, David Smith via swift-evolution <swift-evolution@swift.org> a écrit :

One tricky thing with languages like this (javascript, for example) is that it becomes easy to accidentally introduce a new variable rather than refer to an existing one.

   David

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
   print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
swift-evolution mailing list
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


(Radek Pietruszewski) #4

This is by design:

1. You do have to explicitly declare a variable with let or var to disambiguate, in the eyes of the reader, declaration and assignment. This way, when you see `let x = y`, you know for sure, without double checking, that “x” has no previous value. This is also makes the code more resilient, because if you accidentally reuse a name or whatever, the compiler will warn you.

2. You have to explicitly opt into mutability not to aid the compiler, but to let the compiler aid you!

This teaches you to make immutable things by default, because immutability gives you a guarantee that a thing won’t change. You don’t have to think about it. You’re protected from your future self trying to change a value of a constant. And when you declare a `var`, but don’t need mutability capabilities, the compiler pushes you to change it to `let`, again, to protect yourself from future yourself’s mistakes.

Fun fact: Rust goes even further in pushing you to be immutable by default. Variables are declared by “let x = y”, and to opt into mutability you have to write “mut let x = y”.

— Radek

···

On 24 Feb 2016, at 08:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
  print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

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


(Chris Lattner) #5

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability. The major win of having let and var in the code is that it expresses the intention of what is happening: when you see a “let x = …” you know that x will never be changed.

-Chris

···

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?


#6

There are ways around this.

I like mutability to be explicit, but do like the idea of making `let` optional in cases where it can be assumed a new variable is being introduced:

  let a: String = "string"
  b: String = "string" // short-hand avoids let
  b := "string" // shorter-hand

···

On Feb 24, 2016, at 2:10 AM, David Smith via swift-evolution <swift-evolution@swift.org> wrote:

One tricky thing with languages like this (javascript, for example) is that it becomes easy to accidentally introduce a new variable rather than refer to an existing one.

--
Stephen


(Riley Avron) #7

–1. This would make reading and maintaining code appreciably harder for a
trivial reduction in character count when writing code.

Riley

···

On 23 February 2016 at 23:06, Darko Damjanovic via swift-evolution < swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is
never written to and therefore should be a "let" constant. So now the
compiler knows best if "let" or "var" should be applied. During writing
code I experience repetitive hints about using "let" or "var" so why do I
have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to,
no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability
declarations - just to make them optional. If I still want to write it to
make it clear just by reading thru the code then this is ok. But I can omit
"var and "let" if I want - why bother about it at all if I can go sure
that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let"
optional and "var" still should be explicitly written. So "let" would be
the default and if I want mutability I have explicitly declare it as "var".
This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

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


(Shawn Erickson) #8

I like compact code but not at the cost of code readability and clarity. I
think this degrades the later more then helps the former.

-Shawn

···

On Tue, Feb 23, 2016 at 11:13 PM Darko Damjanovic via swift-evolution < swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is
never written to and therefore should be a "let" constant. So now the
compiler knows best if "let" or "var" should be applied. During writing
code I experience repetitive hints about using "let" or "var" so why do I
have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to,
no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability
declarations - just to make them optional. If I still want to write it to
make it clear just by reading thru the code then this is ok. But I can omit
"var and "let" if I want - why bother about it at all if I can go sure
that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let"
optional and "var" still should be explicitly written. So "let" would be
the default and if I want mutability I have explicitly declare it as "var".
This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss


(Radek Pietruszewski) #9

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

In this way most of your concerns would be relieved:

- if let would be the default (without explicitly typing it) then „x = y“ would lead to a compiler error (if x was declared already before)

This is a fair point, but considering the small cost of typing “let”, I think the benefits of disambiguation and more explicit information for the *reader* are well worth it.

- mutability would be the default generally

I take it you meant “immutability”.

But don’t let me misunderstood - I am not pushing for it. It just feels strange to me that the compiler warns me all the time about something which he already knows (and could solve by himself).

I understand, but again, the point is not for the compiler to “solve” compilation, rather to aid you write correct code.

PS. I didn’t realize Swiftc is a “he”.

···

Imagine you would still have to write retain/release all the time and the compiler would warn you all the time when and how to write it. (that’s what ARC solved eventually)

— Darko

Am 24.02.2016 um 09:45 schrieb Radosław Pietruszewski <radexpl@gmail.com>:

This is by design:

1. You do have to explicitly declare a variable with let or var to disambiguate, in the eyes of the reader, declaration and assignment. This way, when you see `let x = y`, you know for sure, without double checking, that “x” has no previous value. This is also makes the code more resilient, because if you accidentally reuse a name or whatever, the compiler will warn you.

2. You have to explicitly opt into mutability not to aid the compiler, but to let the compiler aid you!

This teaches you to make immutable things by default, because immutability gives you a guarantee that a thing won’t change. You don’t have to think about it. You’re protected from your future self trying to change a value of a constant. And when you declare a `var`, but don’t need mutability capabilities, the compiler pushes you to change it to `let`, again, to protect yourself from future yourself’s mistakes.

Fun fact: Rust goes even further in pushing you to be immutable by default. Variables are declared by “let x = y”, and to opt into mutability you have to write “mut let x = y”.

— Radek

On 24 Feb 2016, at 08:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
  print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

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


(Robert Widmann) #10

-1. In addition, it would imply that all variables are mutable "by default" (a la Python), because all it would take to change an implicit let to an implicit var would be an accidental extra assignment in another branch somewhere.

~Robert Widmann

2016/02/24 16:44、Riley Avron via swift-evolution <swift-evolution@swift.org> のメッセージ:

···

–1. This would make reading and maintaining code appreciably harder for a trivial reduction in character count when writing code.

Riley

On 23 February 2016 at 23:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:
In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
swift-evolution mailing list
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


(Darko Damjanovic) #11

Hello Chris,

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability.

You are right, it would. On the other side - the same is happening already with type inference, right? And to an even greater extent - because: isn't the very type even more important on first sight then the mutability? But it turns out not to be a problem because of the compilers type safety. It doesn't matter what you do with it, you can rest assured that the compiler will take care not to misuse the type in any way. And this is not the only "magic" which is taken care of by the compiler, think about copy-on-write for value types or ARC. All of this is „hidden“ and not clear on first sight.

The major win of having let and var in the code is that it expresses the intention of what is happening: when you see a “let x = …” you know that x will never be changed.

Yes, but now it's not _that_ important anymore, because the compiler can take care of it. Same as with type inference, COW and ARC. The compiler knows better - meanwhile. And same as with type inference you still could write "let" and "var" if it is important in the current context. And if you explicitly want the reader of the code to know about it on first sight.

But I have to admit that making both „let“ and „var" optional without any substitute could lead to problems. Like David Smith wrote:

"it becomes easy to accidentally introduce a new variable rather than refer to an existing one"

Stephen Celis gives a very good solution for this:

let a: String = "string"
b: String = "string" // short-hand avoids let
b := "string" // shorter-hand

I like this. The obvious other solution would be a new keyword (don't like this).

It would not be of a big problem for me if it stay's like it is currently, not at all. It just feels like it's time to move on because the compiler get's smarter and smarter. It was a similar situation with ARC a few years ago if I remember it correctly. At first it was just an additional help for the developer (like the mutability warnings currently) but later it turned out that the compiler already surpasses the developer.

I am new to this list, so sorry about "jumping around" with the proposal. But currently I have no one else to discuss this because I am the only Swift developer in my company. :slight_smile: Please let me know if this kind of discussion is not appropriate on this list. Thanks.

- Darko

···

Am 24.02.2016 um 19:40 schrieb Chris Lattner <clattner@apple.com>:

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability. The major win of having let and var in the code is that it expresses the intention of what is happening: when you see a “let x = …” you know that x will never be changed.

-Chris


(Darko Damjanovic) #12

Hello Mathieu,

If you want to be lazy about it, what about letting the compiler advice you? You could define every new variable as "var", without thinking about it. And after you completed the implementation of the related scope, see what the compiler tells you. And just apply its advice.

Wouldn't that be sufficient?

You are right, I work in a similar way currently. I have my personal rule to commit into Git 100% error _and_ warning free. So I define every new variable as „let“ and if I get a compiler error I change it to "var“. So this is going on all day long - I define „let“ and often the compiler say’s „no - var!“ and I obey. (what else?) :slight_smile: But after doing this game a thousand times I got tired. Asking myself - well, if the compiler knows better anyway, why do _I_ have to tell him all the time? I fully understand the advantages of immutability (that’s why at first „let“ and not „var“) but meanwhile it just feels like boilerplate repetitive code and the machine dictates it to me anyway.

- Darko

···

Am 24.02.2016 um 09:37 schrieb Mathieu Godart <m@godart.co>:

Interesting idea. I like to be able to be lazy! :blush:

But I agree with David. So, we could imagine a new keyword, like "varlet" or "autovar", or whatever to avoid confusion between declaration and assignment... But this would impact drastically the readability. The compiler would know, but not the human reader. And this loss in readability would be very impactful, imho. The mutability character carries a lot of information.

If you want to be lazy about it, what about letting the compiler advice you? You could define every new variable as "var", without thinking about it. And after you completed the implementation of the related scope, see what the compiler tells you. And just apply its advice.

Wouldn't that be sufficient?

Mathieu Godart

PS : This is my first post on this mailing list. So, hello the Swift community!

Le 24 févr. 2016 à 08:10, David Smith via swift-evolution <swift-evolution@swift.org> a écrit :

One tricky thing with languages like this (javascript, for example) is that it becomes easy to accidentally introduce a new variable rather than refer to an existing one.

  David

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
  print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
swift-evolution mailing list
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


(Brent Royal-Gordon) #13

You are right, I work in a similar way currently. I have my personal rule to commit into Git 100% error _and_ warning free. So I define every new variable as „let“ and if I get a compiler error I change it to "var“.

I think the intention is that, before you change it to `var`, you should examine your code and see if there's a way you could write it that would allow it to remain a `let`. Could you assign it to a new constant instead of changing the old variable? Could you use a nonmutating operation instead of a mutating one? It's not that you *have* to take the nonmutating option—`var`s exist in Swift because they're perfectly appropriate in many cases—but if you try to turn `var`-based code into `let`-based code, the `let`-based version is often better.

···

--
Brent Royal-Gordon
Architechies


(Jordan Rose) #14

I'm not particularly happy with this view of type inference. I think the reason it's okay to infer the type of a binding is because it's obvious from context (i.e. the expression). If it's not obvious, you should write it even if the compiler can figure it out for you.

Ideally, code should be written for humans to read, not for compilers to check. I'd like to be able to read a commit and know what it's doing without having to build it.

I'm against "implicit var" on these grounds because it turns out it's much simpler to "look at code and know what it does" if a local variable has the same value the whole time it's used, at least for me. "Implicit var" for locals is the same as not having 'let', because as we've seen in C most people won't bother to use 'let' and its restrictions when it's not the default.

(I'm against "implicit let" for the JavaScript/Python reason of it being too easy to accidentally create a new binding when you meant to modify something in scope or vice versa.)

Jordan

···

On Feb 24, 2016, at 18:26 , Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability.

You are right, it would. On the other side - the same is happening already with type inference, right? And to an even greater extent - because: isn't the very type even more important on first sight then the mutability? But it turns out not to be a problem because of the compilers type safety. It doesn't matter what you do with it, you can rest assured that the compiler will take care not to misuse the type in any way. And this is not the only "magic" which is taken care of by the compiler, think about copy-on-write for value types or ARC. All of this is „hidden“ and not clear on first sight.


(Haravikk) #15

I’m a -1 as well; while I do find the warnings annoying sometimes when a declare a var that I haven’t modified yet, I’d rather have them than not. If there were an option to not decide then developers could end up using it by default just because it’s easier, which could allow a slew of bugs to creep in that Swift currently protects against.

···

On 24 Feb 2016, at 22:52, Developer via swift-evolution <swift-evolution@swift.org> wrote:

-1. In addition, it would imply that all variables are mutable "by default" (a la Python), because all it would take to change an implicit let to an implicit var would be an accidental extra assignment in another branch somewhere.

~Robert Widmann

2016/02/24 16:44、Riley Avron via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

–1. This would make reading and maintaining code appreciably harder for a trivial reduction in character count when writing code.

Riley

On 23 February 2016 at 23:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
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 <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


(Darko Damjanovic) #16

Hello Robert,

I am doing most of the time application development, so I do not need to take care _so_ much about it. But I assume in case of writing lib’s for external usage this could be important, yes. But If you want to explicitly declare immutability just write „let“. Nothing hinders you, right?

- Darko

···

Am 24.02.2016 um 23:52 schrieb Developer <devteam.codafi@gmail.com>:

-1. In addition, it would imply that all variables are mutable "by default" (a la Python), because all it would take to change an implicit let to an implicit var would be an accidental extra assignment in another branch somewhere.

~Robert Widmann

2016/02/24 16:44、Riley Avron via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:

–1. This would make reading and maintaining code appreciably harder for a trivial reduction in character count when writing code.

Riley

On 23 February 2016 at 23:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Craig Cruden) #17

There is quite a bit of difference between type inference and mutable / immutable inference.

Types are important and type safety is important - as it allows the compiler to check during compile time. Type inference does not take away from this - the compiler still checks that a variable / constant is the same type wherever it is used.

It does not matter whether variable “a” is a string. It matters that if “a” is a string, it is always a string.

I do think that “let” is unfortunately scattered throughout the code which makes things like pattern matching less focused/clear - and would appreciate if let is inferred in those circumstances.

“var” should never be inferred.

As far as “let x = …" being inferred, I don’t see much benefit — and quite a bit of risk of variables bleeding unintentionally between different scopes. (let is also pretty standard in math).

···

On 2016-02-25, at 9:26:18, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

Hello Chris,

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability.

You are right, it would. On the other side - the same is happening already with type inference, right? And to an even greater extent - because: isn't the very type even more important on first sight then the mutability? But it turns out not to be a problem because of the compilers type safety. It doesn't matter what you do with it, you can rest assured that the compiler will take care not to misuse the type in any way. And this is not the only "magic" which is taken care of by the compiler, think about copy-on-write for value types or ARC. All of this is „hidden“ and not clear on first sight.

The major win of having let and var in the code is that it expresses the intention of what is happening: when you see a “let x = …” you know that x will never be changed.

Yes, but now it's not _that_ important anymore, because the compiler can take care of it. Same as with type inference, COW and ARC. The compiler knows better - meanwhile. And same as with type inference you still could write "let" and "var" if it is important in the current context. And if you explicitly want the reader of the code to know about it on first sight.

But I have to admit that making both „let“ and „var" optional without any substitute could lead to problems. Like David Smith wrote:

"it becomes easy to accidentally introduce a new variable rather than refer to an existing one"

Stephen Celis gives a very good solution for this:

let a: String = "string"
b: String = "string" // short-hand avoids let
b := "string" // shorter-hand

I like this. The obvious other solution would be a new keyword (don't like this).

It would not be of a big problem for me if it stay's like it is currently, not at all. It just feels like it's time to move on because the compiler get's smarter and smarter. It was a similar situation with ARC a few years ago if I remember it correctly. At first it was just an additional help for the developer (like the mutability warnings currently) but later it turned out that the compiler already surpasses the developer.

I am new to this list, so sorry about "jumping around" with the proposal. But currently I have no one else to discuss this because I am the only Swift developer in my company. :slight_smile: Please let me know if this kind of discussion is not appropriate on this list. Thanks.

- Darko

Am 24.02.2016 um 19:40 schrieb Chris Lattner <clattner@apple.com>:

On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:

In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

The problem with this approach is that you’re favoring writability of the code at the expense of readability/maintainability. The major win of having let and var in the code is that it expresses the intention of what is happening: when you see a “let x = …” you know that x will never be changed.

-Chris

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


(Darko Damjanovic) #18

Hello Gordon,

so what you basically are saying is that the developer still can be smarter then the compiler in this regards. In this case - yes, it would be better to leave it as it is currently. I was not aware of this viewpoint. It seemed to me that the current warnings are already the best possible solution anyway.

In this case my proposal is just to early. Maybe the compiler will evolve in the future in such a way that also immutability/mutability can be better done by the compiler then by the developer.

Nevertheless thanks to all of you for the great input.

Br,
Darko

···

Am 25.02.2016 um 03:37 schrieb Brent Royal-Gordon <brent@architechies.com>:

You are right, I work in a similar way currently. I have my personal rule to commit into Git 100% error _and_ warning free. So I define every new variable as „let“ and if I get a compiler error I change it to "var“.

I think the intention is that, before you change it to `var`, you should examine your code and see if there's a way you could write it that would allow it to remain a `let`. Could you assign it to a new constant instead of changing the old variable? Could you use a nonmutating operation instead of a mutating one? It's not that you *have* to take the nonmutating option—`var`s exist in Swift because they're perfectly appropriate in many cases—but if you try to turn `var`-based code into `let`-based code, the `let`-based version is often better.

--
Brent Royal-Gordon
Architechies


(Robert Widmann) #19

But that's the thing: I don't wish to encourage mutability through the omission of a keyword. (I don't wish to encourage mutability in any case, but that's beside the point!). Your point about types being implicit is entirely different. If type inference does its job, there is no way to apply a term of a certain type as an argument to a function expecting a different type. The same is not true of this scheme of inference. Because I cannot ask swift to guarantee that terms are mutable or immutable, or specify that a function should be pure, I have no immediate guarantees about the mutability of my variables at first glance. That's a level of uncertainty about my code I wouldn't wish to have for any amount of keystroke savings.

~Robert Widmann

2016/02/24 21:34、Darko Damjanovic <darkodamjanovic@me.com> のメッセージ:

···

Hello Robert,

I am doing most of the time application development, so I do not need to take care _so_ much about it. But I assume in case of writing lib’s for external usage this could be important, yes. But If you want to explicitly declare immutability just write „let“. Nothing hinders you, right?

- Darko

Am 24.02.2016 um 23:52 schrieb Developer <devteam.codafi@gmail.com>:

-1. In addition, it would imply that all variables are mutable "by default" (a la Python), because all it would take to change an implicit let to an implicit var would be an accidental extra assignment in another branch somewhere.

~Robert Widmann

2016/02/24 16:44、Riley Avron via swift-evolution <swift-evolution@swift.org> のメッセージ:

–1. This would make reading and maintaining code appreciably harder for a trivial reduction in character count when writing code.

Riley

On 23 February 2016 at 23:06, Darko Damjanovic via swift-evolution <swift-evolution@swift.org> wrote:
In the current Swift version the compiler is warning me if a variable is never written to and therefore should be a "let" constant. So now the compiler knows best if "let" or "var" should be applied. During writing code I experience repetitive hints about using "let" or "var" so why do I have to declare it all the time by myself if the compiler anyway knows best?

My proposal would be to make the declaration of "let" and "var" optional.

Example:
x = 0 // <- implicitly declared as "var x" because later was written to, no need to declare it manually
x = 5

Example:
y = 0 // <- implicitly declared as "let y" because later was not written to
print(y)

Example Optional Binding:
if index = myArray.indexOf("A") {
        print(index) // here it's clear that index can be "let index"
}

etc...

This would _not_ mean to disallow or remove the "var and "let" mutability declarations - just to make them optional. If I still want to write it to make it clear just by reading thru the code then this is ok. But I can omit "var and "let" if I want - why bother about it at all if I can go sure that the compiler is already doing the best?

Another option (if this is "too much" change) would be to just make "let" optional and "var" still should be explicitly written. So "let" would be the default and if I want mutability I have explicitly declare it as "var". This is already the rule for function parameters.

Kind regards,
Darko Damjanovic-Lichtfuss

_______________________________________________
swift-evolution mailing list
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


(Angelo Villegas) #20

Writability over maintainability? I'm going to vote against this, so -1.

···

On Thu, 25 Feb 2016 at 10:43 AM Craig Cruden via swift-evolution < swift-evolution@swift.org> wrote:

There is quite a bit of difference between type inference and mutable /
immutable inference.

Types are important and type safety is important - as it allows the
compiler to check during compile time. Type inference does not take away
from this - the compiler still checks that a variable / constant is the
same type wherever it is used.

It does not matter whether variable “a” is a string. It matters that if
“a” is a string, it is always a string.

I do think that “let” is unfortunately scattered throughout the code which
makes things like pattern matching less focused/clear - and would
appreciate if let is inferred in those circumstances.

“var” should never be inferred.

As far as “let x = …" being inferred, I don’t see much benefit — and quite
a bit of risk of variables bleeding unintentionally between different
scopes. (let is also pretty standard in math).

> On 2016-02-25, at 9:26:18, Darko Damjanovic via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Hello Chris,
>
>> The problem with this approach is that you’re favoring writability of
the code at the expense of readability/maintainability.
>
> You are right, it would. On the other side - the same is happening
already with type inference, right? And to an even greater extent -
because: isn't the very type even more important on first sight then the
mutability? But it turns out not to be a problem because of the compilers
type safety. It doesn't matter what you do with it, you can rest assured
that the compiler will take care not to misuse the type in any way. And
this is not the only "magic" which is taken care of by the compiler, think
about copy-on-write for value types or ARC. All of this is „hidden“ and not
clear on first sight.
>
>> The major win of having let and var in the code is that it expresses
the intention of what is happening: when you see a “let x = …” you know
that x will never be changed.
>
> Yes, but now it's not _that_ important anymore, because the compiler can
take care of it. Same as with type inference, COW and ARC. The compiler
knows better - meanwhile. And same as with type inference you still could
write "let" and "var" if it is important in the current context. And if you
explicitly want the reader of the code to know about it on first sight.
>
> But I have to admit that making both „let“ and „var" optional without
any substitute could lead to problems. Like David Smith wrote:
>
> "it becomes easy to accidentally introduce a new variable rather than
refer to an existing one"
>
> Stephen Celis gives a very good solution for this:
>
> let a: String = "string"
> b: String = "string" // short-hand avoids let
> b := "string" // shorter-hand
>
> I like this. The obvious other solution would be a new keyword (don't
like this).
>
> It would not be of a big problem for me if it stay's like it is
currently, not at all. It just feels like it's time to move on because the
compiler get's smarter and smarter. It was a similar situation with ARC a
few years ago if I remember it correctly. At first it was just an
additional help for the developer (like the mutability warnings currently)
but later it turned out that the compiler already surpasses the developer.
>
> I am new to this list, so sorry about "jumping around" with the
proposal. But currently I have no one else to discuss this because I am the
only Swift developer in my company. :slight_smile: Please let me know if this kind of
discussion is not appropriate on this list. Thanks.
>
> - Darko
>
>
>
>
>> Am 24.02.2016 um 19:40 schrieb Chris Lattner <clattner@apple.com>:
>>
>>
>>> On Feb 23, 2016, at 11:06 PM, Darko Damjanovic via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> In the current Swift version the compiler is warning me if a variable
is never written to and therefore should be a "let" constant. So now the
compiler knows best if "let" or "var" should be applied. During writing
code I experience repetitive hints about using "let" or "var" so why do I
have to declare it all the time by myself if the compiler anyway knows best?
>>
>> The problem with this approach is that you’re favoring writability of
the code at the expense of readability/maintainability. The major win of
having let and var in the code is that it expresses the intention of what
is happening: when you see a “let x = …” you know that x will never be
changed.
>>
>> -Chris
>>
>
> _______________________________________________
> swift-evolution mailing list
> 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