Proposal Idea: Use of == outside of comparisons should be treated as an error.


(Jared Sinclair) #1

Consider the following:

protocol Updatable {
func update(state: Bool)
}

class Thing: Updatable {
private var enabled = false

func update\(state: Bool\) \{
    self\.enabled == state
\}

}

The obvious intention is to set self.enabled to the incoming value of state. However, it’s easy to accidentally type a second equals sign. The effect of this typo is self.enabled is never updated, leading to a run-time bug that could be difficult to diagnose.

This typo doesn’t generate any errors or warnings. I can’t think of a valid reason to use the equals function outside of comparisons. If the compiler instead treated this typo as an error, the mistake would be trivial to identify and fix:

protocol Updatable {
func update(state: Bool)
}

class Thing: Updatable {
private var enabled = false

func update\(state: Bool\) \{
    self\.enabled == state // Error: \`==\` may not be used outside of comparisons
\}

}

···

--
Jared Sinclair
Sent with Airmail


(Joe Groff) #2

If it isn't already, the implementation of `==` ought to be marked with the `@warn_unused_result` attribute, which will give you a warning if the result is ignored. We're discussing making warn_unused_result the default behavior in another thread.

-Joe

···

On Jan 11, 2016, at 12:39 PM, Jared Sinclair via swift-evolution <swift-evolution@swift.org> wrote:

Consider the following:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false
    
    func update(state: Bool) {
        self.enabled == state
    }
}

The obvious intention is to set self.enabled to the incoming value of state. However, it’s easy to accidentally type a second equals sign. The effect of this typo is self.enabled is never updated, leading to a run-time bug that could be difficult to diagnose.

This typo doesn’t generate any errors or warnings. I can’t think of a valid reason to use the equals function outside of comparisons. If the compiler instead treated this typo as an error, the mistake would be trivial to identify and fix:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false
    
    func update(state: Bool) {
        self.enabled == state // Error: `==` may not be used outside of comparisons
    }
}


(John Randolph) #3

I’d consider that warning sufficient to keep me from making this mistake. Making it an error seems like overkill.

-jcr

···

On Jan 11, 2016, at 12:45 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

If it isn't already, the implementation of `==` ought to be marked with the `@warn_unused_result` attribute, which will give you a warning if the result is ignored. We're discussing making warn_unused_result the default behavior in another thread.

-Joe


(Andrew Bennett) #4

I'm +1 on @warn_unused_result, does that need a proposal or is a PR
sufficient?

···

On Tue, Jan 12, 2016 at 7:45 AM, Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:

On Jan 11, 2016, at 12:39 PM, Jared Sinclair via swift-evolution < > swift-evolution@swift.org> wrote:

Consider the following:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state
    }
}

The obvious intention is to set self.enabled to the incoming value of
state. However, it’s easy to accidentally type a second equals sign. The
effect of this typo is self.enabled is never updated, leading to a
run-time bug that could be difficult to diagnose.

This typo doesn’t generate any errors or warnings. I can’t think of a
valid reason to use the equals function outside of comparisons. If the
compiler instead treated this typo as an error, the mistake would be
trivial to identify and fix:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state // Error: `==` may not be used outside of
comparisons
    }
}

If it isn't already, the implementation of `==` ought to be marked with
the `@warn_unused_result` attribute, which will give you a warning if the
result is ignored. We're discussing making warn_unused_result the default
behavior in another thread.

-Joe

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


(Dmitri Gribenko) #5

A pull request to the standard library would be appreciated.

Dmitri

···

On Tue, Jan 12, 2016 at 1:01 PM, Andrew Bennett via swift-evolution < swift-evolution@swift.org> wrote:

I'm +1 on @warn_unused_result, does that need a proposal or is a PR
sufficient?

On Tue, Jan 12, 2016 at 7:45 AM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:

On Jan 11, 2016, at 12:39 PM, Jared Sinclair via swift-evolution < >> swift-evolution@swift.org> wrote:

Consider the following:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state
    }
}

The obvious intention is to set self.enabled to the incoming value of
state. However, it’s easy to accidentally type a second equals sign. The
effect of this typo is self.enabled is never updated, leading to a
run-time bug that could be difficult to diagnose.

This typo doesn’t generate any errors or warnings. I can’t think of a
valid reason to use the equals function outside of comparisons. If the
compiler instead treated this typo as an error, the mistake would be
trivial to identify and fix:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state // Error: `==` may not be used outside of
comparisons
    }
}

If it isn't already, the implementation of `==` ought to be marked with
the `@warn_unused_result` attribute, which will give you a warning if the
result is ignored. We're discussing making warn_unused_result the default
behavior in another thread.

-Joe

_______________________________________________
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

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Alex Johnson) #6

I think @warn_unused_result is already present on ==, at least for Bool in
Swift 2.1.1.

For example:

$ swift --version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.2.0

$ cat test.swift
var a = true
let b = false

func doStuff() {
  a == b
}

$ swift test.swift
test.swift:5:5: warning: result of call to '==' is unused
  a == b
    ^

Warnings aren't shown in Playgrounds or in the REPL, though, so if you're
running code there you won't see it.

···

On Tue, Jan 12, 2016 at 1:01 PM, Andrew Bennett via swift-evolution < swift-evolution@swift.org> wrote:

I'm +1 on @warn_unused_result, does that need a proposal or is a PR
sufficient?

On Tue, Jan 12, 2016 at 7:45 AM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:

On Jan 11, 2016, at 12:39 PM, Jared Sinclair via swift-evolution < >> swift-evolution@swift.org> wrote:

Consider the following:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state
    }
}

The obvious intention is to set self.enabled to the incoming value of
state. However, it’s easy to accidentally type a second equals sign. The
effect of this typo is self.enabled is never updated, leading to a
run-time bug that could be difficult to diagnose.

This typo doesn’t generate any errors or warnings. I can’t think of a
valid reason to use the equals function outside of comparisons. If the
compiler instead treated this typo as an error, the mistake would be
trivial to identify and fix:

protocol Updatable {
    func update(state: Bool)
}

class Thing: Updatable {
    private var enabled = false

    func update(state: Bool) {
        self.enabled == state // Error: `==` may not be used outside of
comparisons
    }
}

If it isn't already, the implementation of `==` ought to be marked with
the `@warn_unused_result` attribute, which will give you a warning if the
result is ignored. We're discussing making warn_unused_result the default
behavior in another thread.

-Joe

_______________________________________________
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

--

*Alex Johnson | Engineering Lead*

*Quick Left, Inc. <https://quickleft.com/>*
*Boulder **|* *Denver* *|* *Portland** |** San Francisco*

1 (844) QL-NERDS

@nonsensery

<https://github.com/quickleft> <https://www.facebook.com/quickleft>
<https://twitter.com/quickleft> <https://instagram.com/quick_left/>
<https://www.flickr.com/photos/quickleft> <https://vimeo.com/quickleft>

*What's it like to work with us? **TrainingPeaks, iTriage, and Ping
Identity share their stories in this short video** A Client's View
<https://vimeo.com/92286352>*.