Allowing `guard let self = self else { … }` for weakly captured self in a closure


(Hoon H.) #1

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.


The Future Of [weak self] Rebinding
(Jordan Rose) #2

This has come up before, in a thread called "Proposal: weakStrong self in completion handler closures". I'm still not 100% happy with the syntax, but I like that "guard let" can handle non-Void non-Optional returns well, while 'weakStrong' cannot.

Jordan

···

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution <swift-evolution@swift.org> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.

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


(Jacob Bandes-Storch) #3

+1.

Merely using "self?.something" repeatedly might produce unexpected
behavior, if self becomes nil between calls. As I mentioned in another
thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy "strongSelf.property"
all over the place.

I agree with Jordan that "guard let self = self" isn't the most satisfying
syntax, but it has the advantage of being a *very* minimal grammar/syntax
change, and its behavior is completely clear as long as the user is already
familiar with guard.

We should also consider whether "self." is required after "guard let self =
self". An explicit "guard let self = self" avoids the accidental-capture
problem, so I think it's reasonable to allow unqualified property access
for the remainder of the scope.

Jacob

···

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution < swift-evolution@swift.org> wrote:

This has come up before, in a thread called "Proposal: weakStrong self in
completion handler closures". I'm still not 100% happy with the syntax,
but I like that "guard let" can handle non-Void non-Optional returns well,
while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution < > swift-evolution@swift.org> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with
same name, and emits a compiler error.

class Foo {
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
guard let self = self else { return } // Error.
print(self)
}
}
}

Do we have any reason to disallow making `self` back to strong reference?
It’d be nice if I can do it. Please consider this case.

class Foo {
func getValue1() -> Int {
return 1234
}
func test3(value: Int) {
print(value)
}
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

self!.test3(self!.getValue1()) // Considered harmful due to `!`.

guard self != nil else { return }
self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

guard let self1 = self else { return }
self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary
new name `self1`.

guard let self = self else { return }
self.test3(self.getValue1()) // OK.

}
}
}

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after
`guard let …` if appropriate.

guard let self = self else { return }
test3(getValue1()) // Referencing to `self` would not be required anymore.
Seems arguable.

I think this is almost fine because users have to express their intention
explicitly with `guard` statement. If someone erases the `guard` later,
compiler will require explicit self again, and that will prevent mistakes.
But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at
least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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


(Jacob Bandes-Storch) #4

FWIW, in a codebase of ~150 Swift files, I see 18 occurrences of "let
strongSelf = self", and 26 occurrences of "self?." (which should arguably
be changed to the former).

Jacob

···

On Tue, Jan 5, 2016 at 5:46 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

+1.

Merely using "self?.something" repeatedly might produce unexpected
behavior, if self becomes nil between calls. As I mentioned in another
thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy "strongSelf.property"
all over the place.

I agree with Jordan that "guard let self = self" isn't the most satisfying
syntax, but it has the advantage of being a *very* minimal grammar/syntax
change, and its behavior is completely clear as long as the user is already
familiar with guard.

We should also consider whether "self." is required after "guard let self
= self". An explicit "guard let self = self" avoids the accidental-capture
problem, so I think it's reasonable to allow unqualified property access
for the remainder of the scope.

Jacob

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution < > swift-evolution@swift.org> wrote:

This has come up before, in a thread called "Proposal: weakStrong self
in completion handler closures". I'm still not 100% happy with the
syntax, but I like that "guard let" can handle non-Void non-Optional
returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution < >> swift-evolution@swift.org> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with
same name, and emits a compiler error.

class Foo {
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
guard let self = self else { return } // Error.
print(self)
}
}
}

Do we have any reason to disallow making `self` back to strong reference?
It’d be nice if I can do it. Please consider this case.

class Foo {
func getValue1() -> Int {
return 1234
}
func test3(value: Int) {
print(value)
}
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

self!.test3(self!.getValue1()) // Considered harmful due to `!`.

guard self != nil else { return }
self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

guard let self1 = self else { return }
self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary
new name `self1`.

guard let self = self else { return }
self.test3(self.getValue1()) // OK.

}
}
}

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after
`guard let …` if appropriate.

guard let self = self else { return }
test3(getValue1()) // Referencing to `self` would not be required
anymore. Seems arguable.

I think this is almost fine because users have to express their intention
explicitly with `guard` statement. If someone erases the `guard` later,
compiler will require explicit self again, and that will prevent mistakes.
But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at
least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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


(Jacob Bandes-Storch) #5

Wow! I didn't know that worked. It's a bit surprising, and perhaps not
intended. I think the proposal is still valid.

···

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers <christorogers@gmail.com> wrote:

You can shadow self with a guard like you wrote it if use the keyword
escaping backquotes like so:

guard let `self` = self else { return }
On Wed, Jan 6, 2016 at 10:55 AM Jacob Bandes-Storch via swift-evolution < > swift-evolution@swift.org> wrote:

FWIW, in a codebase of ~150 Swift files, I see 18 occurrences of "let
strongSelf = self", and 26 occurrences of "self?." (which should arguably
be changed to the former).

Jacob

On Tue, Jan 5, 2016 at 5:46 PM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

+1.

Merely using "self?.something" repeatedly might produce unexpected
behavior, if self becomes nil between calls. As I mentioned in another
thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy
"strongSelf.property" all over the place.

I agree with Jordan that "guard let self = self" isn't the most
satisfying syntax, but it has the advantage of being a *very* minimal
grammar/syntax change, and its behavior is completely clear as long as the
user is already familiar with guard.

We should also consider whether "self." is required after "guard let
self = self". An explicit "guard let self = self" avoids the
accidental-capture problem, so I think it's reasonable to allow unqualified
property access for the remainder of the scope.

Jacob

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution < >>> swift-evolution@swift.org> wrote:

This has come up before, in a thread called "Proposal: weakStrong self
in completion handler closures". I'm still not 100% happy with the
syntax, but I like that "guard let" can handle non-Void non-Optional
returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution < >>>> swift-evolution@swift.org> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with
same name, and emits a compiler error.

class Foo {
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
guard let self = self else { return } // Error.
print(self)
}
}
}

Do we have any reason to disallow making `self` back to strong
reference? It’d be nice if I can do it. Please consider this case.

class Foo {
func getValue1() -> Int {
return 1234
}
func test3(value: Int) {
print(value)
}
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
self?.test3(self?.getValue1()) // Doesn't work because it's not
unwrapped.

self!.test3(self!.getValue1()) // Considered harmful due to `!`.

guard self != nil else { return }
self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

guard let self1 = self else { return }
self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary
new name `self1`.

guard let self = self else { return }
self.test3(self.getValue1()) // OK.

}
}
}

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self`
after `guard let …` if appropriate.

guard let self = self else { return }
test3(getValue1()) // Referencing to `self` would not be required
anymore. Seems arguable.

I think this is almost fine because users have to express their
intention explicitly with `guard` statement. If someone erases the `guard`
later, compiler will require explicit self again, and that will prevent
mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked
at least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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

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


(Greg Parker) #6

Does further use of self after that actually use a strong shadowing variable? Or does it go back to the weak reference it already had as if the shadow were not there?

···

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers <christorogers@gmail.com <mailto:christorogers@gmail.com>> wrote:
You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }


(Jacob Bandes-Storch) #7

Yes, it seems to use the strong shadowing variable. (The compiler doesn't
complain about "self.foo", and "self?.foo" becomes invalid because self is
no longer optional.)

If it weren't so useful, I'd call it a bug.

···

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com> wrote:

Does further use of self after that actually use a strong shadowing
variable? Or does it go back to the weak reference it already had as if the
shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution < > swift-evolution@swift.org> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not
intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers < > christorogers@gmail.com> wrote:

You can shadow self with a guard like you wrote it if use the keyword
escaping backquotes like so:

guard let `self` = self else { return }


(Greg Parker) #8

I think it is a bug :slight_smile: That's not what backquotes are for. It ought to be either supported without the backquotes or banned regardless of backquotes.

···

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Yes, it seems to use the strong shadowing variable. (The compiler doesn't complain about "self.foo", and "self?.foo" becomes invalid because self is no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com <mailto:gparker@apple.com>> wrote:
Does further use of self after that actually use a strong shadowing variable? Or does it go back to the weak reference it already had as if the shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers <christorogers@gmail.com <mailto:christorogers@gmail.com>> wrote:
You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }


(Kevin Ballard) #9

I actually expected it to create a different identifier that is
unrelated to the keyword, so you can refer to `self` with backticks in
the future to get the version bound by the guard, and self as a keyword
to get the original value of self.

Not that I think this is particularly useful, of course...

-Kevin Ballard

···

On Tue, Jan 5, 2016, at 08:42 PM, Greg Parker via swift-evolution wrote:

I think it is a bug :slight_smile: That's not what backquotes are for. It ought
to be either supported without the backquotes or banned regardless of
backquotes.

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch >> <jtbandes@gmail.com> wrote:

Yes, it seems to use the strong shadowing variable. (The compiler
doesn't complain about "self.foo", and "self?.foo" becomes invalid
because self is no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker >> <gparker@apple.com> wrote:

Does further use of self after that actually use a strong shadowing
variable? Or does it go back to the weak reference it already had as
if the shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution >>>> <swift-evolution@swift.org> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps
not intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers >>>> <christorogers@gmail.com> wrote:

You can shadow self with a guard like you wrote it if use the
keyword escaping backquotes like so:

guard let `self` = self else { return }

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


(Christopher Rogers) #10

You can shadow self with a guard like you wrote it if use the keyword
escaping backquotes like so:

guard let `self` = self else { return }

···

On Wed, Jan 6, 2016 at 10:55 AM Jacob Bandes-Storch via swift-evolution < swift-evolution@swift.org> wrote:

FWIW, in a codebase of ~150 Swift files, I see 18 occurrences of "let
strongSelf = self", and 26 occurrences of "self?." (which should arguably
be changed to the former).

Jacob

On Tue, Jan 5, 2016 at 5:46 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

+1.

Merely using "self?.something" repeatedly might produce unexpected
behavior, if self becomes nil between calls. As I mentioned in another
thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy "strongSelf.property"
all over the place.

I agree with Jordan that "guard let self = self" isn't the most
satisfying syntax, but it has the advantage of being a *very* minimal
grammar/syntax change, and its behavior is completely clear as long as the
user is already familiar with guard.

We should also consider whether "self." is required after "guard let self
= self". An explicit "guard let self = self" avoids the accidental-capture
problem, so I think it's reasonable to allow unqualified property access
for the remainder of the scope.

Jacob

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution < >> swift-evolution@swift.org> wrote:

This has come up before, in a thread called "Proposal: weakStrong self
in completion handler closures". I'm still not 100% happy with the
syntax, but I like that "guard let" can handle non-Void non-Optional
returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution < >>> swift-evolution@swift.org> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with
same name, and emits a compiler error.

class Foo {
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
guard let self = self else { return } // Error.
print(self)
}
}
}

Do we have any reason to disallow making `self` back to strong
reference? It’d be nice if I can do it. Please consider this case.

class Foo {
func getValue1() -> Int {
return 1234
}
func test3(value: Int) {
print(value)
}
func test2(f: ()->()) {
// …
}
func test1() {
test2 { [weak self] in
self?.test3(self?.getValue1()) // Doesn't work because it's not
unwrapped.

self!.test3(self!.getValue1()) // Considered harmful due to `!`.

guard self != nil else { return }
self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

guard let self1 = self else { return }
self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary
new name `self1`.

guard let self = self else { return }
self.test3(self.getValue1()) // OK.

}
}
}

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self`
after `guard let …` if appropriate.

guard let self = self else { return }
test3(getValue1()) // Referencing to `self` would not be required
anymore. Seems arguable.

I think this is almost fine because users have to express their
intention explicitly with `guard` statement. If someone erases the `guard`
later, compiler will require explicit self again, and that will prevent
mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked
at least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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

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


(Paul Cantrell) #11

Ummm … isn’t that _exactly_ what backticks are for? From the docs:

    To use a reserved word as an identifier, put a backtick (`) before and after it.

···

On Jan 5, 2016, at 10:42 PM, Greg Parker via swift-evolution <swift-evolution@swift.org> wrote:

I think it is a bug :slight_smile: That's not what backquotes are for. It ought to be either supported without the backquotes or banned regardless of backquotes.

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Yes, it seems to use the strong shadowing variable. (The compiler doesn't complain about "self.foo", and "self?.foo" becomes invalid because self is no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com <mailto:gparker@apple.com>> wrote:
Does further use of self after that actually use a strong shadowing variable? Or does it go back to the weak reference it already had as if the shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers <christorogers@gmail.com <mailto:christorogers@gmail.com>> wrote:
You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }

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


(Chris Lattner) #12

To confirm what others have said down thread, this is a compiler bug: this code is valid, but shouldn’t change what references to “self.method()” or “method()" bind to (i.e., explicit or implicit references to self).

Backquotes are for forming a name that happens to overlap with a keyword. In the case of `self`, this could be because you want to refer to the NSObject.`self` method for some reason. Backquotes are not a way to name self, init, subscript or any of the other declarations that look like magic identifiers.

-Chris

···

On Jan 5, 2016, at 8:21 PM, Christopher Rogers via swift-evolution <swift-evolution@swift.org> wrote:

You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }


(Hoon H.) #13

Apart of the compiler back-tick bug, I like to proceed this proposal from "Socialize the idea” stage to "Develop the proposal” stage. (https://github.com/apple/swift-evolution/blob/master/process.md#how-to-propose-a-change) by writing a formal proposal using template because I think some people are interested in my proposal.

For Jordan’s comment, I like to point that closure capturing list syntax already allows very similar rebinding of “self” which changes only referencing semantics (strong -> weak), so I think this is pretty consistent.

    { [weak self = self] in
        guard let self = self else { return }
        print(self)
    }

And I am not sure what to do for the prior proposal "Proposal: weakStrong self in completion handler closures” by Jacob. My original intention was about rebinding of “self”, and then, I realised that eliding “self” qualification can make sense with guard statement. So I think my proposal is different thing, but I have strong sense of duty to do something with it because Jordan explicitly mentioned it. Can someone point me what is the best behaviour in this case?

P.S. I think I have sent an empty message to this mailing list. Sorry for that if it happened. This is actually my first long discussion experience with mailing-list stuff. It’s confusing how to use this mailing list stuff...

— Hoon H.

···

On 2016/01/06, at 09:02 AM, Hoon H. <drawtree@gmail.com> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.


(Hoon H.) #14

I like to point that closure capturing list syntax already allows very similar rebinding of “self” which changes only referencing semantics (strong -> weak), so I think this is pretty consistent.

   { [weak self = self] in
       // ...
   }

For the prior proposal "Proposal: weakStrong self in completion handler closures” (by Jacob Bandes-Storch), I think my proposal is different thing.
My original intention was about rebinding of “self”, and then, I realised that eliding “self” qualification can make sense with guard statement and introduced it as an extra feature. I think it’s fine to develop my proposal separately, but please tell me if you have some opinions.

— Hoon H.

···

On 2016/01/06, at 09:20 AM, Jordan Rose <jordan_rose@apple.com> wrote:

This has come up before, in a thread called "Proposal: weakStrong self in completion handler closures". I'm still not 100% happy with the syntax, but I like that "guard let" can handle non-Void non-Optional returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.

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


(Hoon H.) #15

Thanks for your opinions.
I am writing a formal proposal, and now I think it’d be fine to elide explicit `self` qualification after `guard let … `.

Also for your proposal, though I think mine is originated from different intention, but final conclusion overlaps with your intention, and I am still not sure what to do in this situation. Do you have some opinions?

— Hoon H.

···

On 2016/01/06, at 10:46 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

+1.

Merely using "self?.something" repeatedly might produce unexpected behavior, if self becomes nil between calls. As I mentioned in another thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy "strongSelf.property" all over the place.

I agree with Jordan that "guard let self = self" isn't the most satisfying syntax, but it has the advantage of being a very minimal grammar/syntax change, and its behavior is completely clear as long as the user is already familiar with guard.

We should also consider whether "self." is required after "guard let self = self". An explicit "guard let self = self" avoids the accidental-capture problem, so I think it's reasonable to allow unqualified property access for the remainder of the scope.

Jacob

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
This has come up before, in a thread called "Proposal: weakStrong self in completion handler closures". I'm still not 100% happy with the syntax, but I like that "guard let" can handle non-Void non-Optional returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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


(Jacob Bandes-Storch) #16

Not exactly; backticks are for making an identifier out of something that's
not normally an identifier. Most other reserved words are used in control
flow & other declarations. Rarely do they actually represent
identifiers/values that you can work with.

The docs also say "The backticks are not considered part of the identifier;
`x` and x have the same meaning." Thus `self` and self should have the same
meaning. Assigning to `self` is the same as assigning to self, which
intentionally isn't allowed. Backticks shouldn't allow you to circumvent
that.

Jacob

···

On Wed, Jan 6, 2016 at 12:50 PM, Paul Cantrell <paul@innig.net> wrote:

Ummm … isn’t that _exactly_ what backticks are for? From the docs:

    To use a reserved word as an identifier, put a backtick (`) before
and after it.

On Jan 5, 2016, at 10:42 PM, Greg Parker via swift-evolution < > swift-evolution@swift.org> wrote:

I think it is a bug :slight_smile: That's not what backquotes are for. It ought to
be either supported without the backquotes or banned regardless of
backquotes.

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Yes, it seems to use the strong shadowing variable. (The compiler doesn't
complain about "self.foo", and "self?.foo" becomes invalid because self is
no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com> wrote:

Does further use of self after that actually use a strong shadowing
variable? Or does it go back to the weak reference it already had as if the
shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution < >> swift-evolution@swift.org> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not
intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers < >> christorogers@gmail.com> wrote:

You can shadow self with a guard like you wrote it if use the keyword
escaping backquotes like so:

guard let `self` = self else { return }

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


(Paul Cantrell) #17

But “self” _is_ a reserved word, and that’s the whole reason that this proposal is necessary in the first place. If “self” were just a normal identifier, then “if let self = self” would work just as well as “if let foo = foo” and there would be nothing to discuss.

The docs also say "The backticks are not considered part of the identifier; `x` and x have the same meaning." Thus `self` and self should have the same meaning.

Well, `flurtzle` and flurtzle would have the same meaning, but `self` is an identifier whereas as self is a keyword, so they mean different things. That is precisely what the backticks are for.

Assigning to `self` is the same as assigning to self, which intentionally isn't allowed.

No, you’re creating a new identifier called “self” which shadows the old one.

Consider this:

    let foo: Int? = 7
    if let foo = foo {
        print(foo + 1)
    }

There are two identifiers named foo, one optional, one not. Both are declared with “let”, so neither can be assigned to. But the code works. Why? Because “let foo = foo” doesn’t assign to the outer variable; it creates a new one. If self were not a keyword, then it would work the same as “foo” above.

Cheers,

Paul

···

On Jan 6, 2016, at 2:56 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Not exactly; backticks are for making an identifier out of something that's not normally an identifier. Most other reserved words are used in control flow & other declarations. Rarely do they actually represent identifiers/values that you can work with.

The docs also say "The backticks are not considered part of the identifier; `x` and x have the same meaning." Thus `self` and self should have the same meaning. Assigning to `self` is the same as assigning to self, which intentionally isn't allowed. Backticks shouldn't allow you to circumvent that.

Jacob

On Wed, Jan 6, 2016 at 12:50 PM, Paul Cantrell <paul@innig.net <mailto:paul@innig.net>> wrote:
Ummm … isn’t that _exactly_ what backticks are for? From the docs:

    To use a reserved word as an identifier, put a backtick (`) before and after it.

On Jan 5, 2016, at 10:42 PM, Greg Parker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I think it is a bug :slight_smile: That's not what backquotes are for. It ought to be either supported without the backquotes or banned regardless of backquotes.

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Yes, it seems to use the strong shadowing variable. (The compiler doesn't complain about "self.foo", and "self?.foo" becomes invalid because self is no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com <mailto:gparker@apple.com>> wrote:
Does further use of self after that actually use a strong shadowing variable? Or does it go back to the weak reference it already had as if the shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers <christorogers@gmail.com <mailto:christorogers@gmail.com>> wrote:
You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }

_______________________________________________
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


(Jordan Rose) #18

…which we ought to fix by not reusing Identifier data for the keywords. :wink:

Jordan

···

On Jan 22, 2016, at 17:51, Chris Lattner <clattner@apple.com> wrote:

On Jan 5, 2016, at 8:21 PM, Christopher Rogers via swift-evolution <swift-evolution@swift.org> wrote:

You can shadow self with a guard like you wrote it if use the keyword escaping backquotes like so:

guard let `self` = self else { return }

To confirm what others have said down thread, this is a compiler bug: this code is valid, but shouldn’t change what references to “self.method()” or “method()" bind to (i.e., explicit or implicit references to self).

Backquotes are for forming a name that happens to overlap with a keyword. In the case of `self`, this could be because you want to refer to the NSObject.`self` method for some reason. Backquotes are not a way to name self, init, subscript or any of the other declarations that look like magic identifiers.


(E. Maloney) #19

I'm way-late to this discussion—I don't know how any of you get any coding done trying to keep up with this mailing list!—but anyway...

I propose:

let doSomething: () -> Void = { [guard self] in
    ...
}

[guard self] would effectively work like [weak self] in that it doesn't cause the closure itself to hold a strong reference to whatever is pointed to by self. But if self is still around when the closure is called, it upgrades it to a strong reference for the duration of the closure's execution.

So, when doSomething() is just sitting around not doing something, it doesn't prevent self from being deallocated.

If, by the time doSomething() is called, self is no longer there, doSomething() just returns without the closure executing. If self is there, then the closure executes with self as a strong reference inside.

That way, self within the closure is already strong, so you can use it conveniently as a non-optional and without doing the strongSelf = self dance. You get the memory management benefit of a weak reference without the extra noise in your code needed to support it.

Ok, so what closures with a return value, you ask? How about something like:

let maybeDoSomething: () -> Bool = { [guard self else false] in
    ...
}

Here, maybeDoSomething() doesn't hold a strong reference to self. If it executes when self is still alive, the code within the braces executes with self as a strong reference. If self is gone, the value after the else is returned (the "return" itself is implied).

What do you think?

···

On Jan 28, 2016, at 7:32 PM, Hoon H. via swift-evolution <swift-evolution@swift.org> wrote:

Thanks for your opinions.
I am writing a formal proposal, and now I think it’d be fine to elide explicit `self` qualification after `guard let … `.

Also for your proposal, though I think mine is originated from different intention, but final conclusion overlaps with your intention, and I am still not sure what to do in this situation. Do you have some opinions?

— Hoon H.

On 2016/01/06, at 10:46 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

+1.

Merely using "self?.something" repeatedly might produce unexpected behavior, if self becomes nil between calls. As I mentioned in another thread, in Obj-C, there is a warning for this (-Warc-repeated-use-of-weak).

In many cases, I use the pattern

    somethingAsync { [weak self] in
        guard let strongSelf = self else { return }

        // use strongSelf below
    }

But of course, this leads to the unnatural/unwieldy "strongSelf.property" all over the place.

I agree with Jordan that "guard let self = self" isn't the most satisfying syntax, but it has the advantage of being a very minimal grammar/syntax change, and its behavior is completely clear as long as the user is already familiar with guard.

We should also consider whether "self." is required after "guard let self = self". An explicit "guard let self = self" avoids the accidental-capture problem, so I think it's reasonable to allow unqualified property access for the remainder of the scope.

Jacob

On Tue, Jan 5, 2016 at 4:20 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
This has come up before, in a thread called "Proposal: weakStrong self in completion handler closures". I'm still not 100% happy with the syntax, but I like that "guard let" can handle non-Void non-Optional returns well, while 'weakStrong' cannot.

Jordan

On Jan 5, 2016, at 16:02, Hoon H. via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Currently, weakly captured `self` cannot be bound to `guard let …` with same name, and emits a compiler error.

  class Foo {
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        guard let self = self else { return } // Error.
        print(self)
      }
    }
  }

Do we have any reason to disallow making `self` back to strong reference? It’d be nice if I can do it. Please consider this case.

  class Foo {
    func getValue1() -> Int {
      return 1234
    }
    func test3(value: Int) {
      print(value)
    }
    func test2(f: ()->()) {
      // …
    }
    func test1() {
      test2 { [weak self] in
        self?.test3(self?.getValue1()) // Doesn't work because it's not unwrapped.

        self!.test3(self!.getValue1()) // Considered harmful due to `!`.

        guard self != nil else { return }
        self!.test3(self!.getValue1()) // OK, but still looks and feels harmful.

        guard let self1 = self else { return }
        self1.test3(self1.getValue1()) // OK, but feels ugly due to unnecessary new name `self1`.

        guard let self = self else { return }
        self.test3(self.getValue1()) // OK.

      }
    }
  }

This also can be applied to `if let` or same sort of constructs.

Even further, we can consider removing required reference to `self` after `guard let …` if appropriate.

  guard let self = self else { return }
  test3(getValue1()) // Referencing to `self` would not be required anymore. Seems arguable.

I think this is almost fine because users have to express their intention explicitly with `guard` statement. If someone erases the `guard` later, compiler will require explicit self again, and that will prevent mistakes. But still, I am not sure this removal would be perfectly fine.

I am not sure whether this is already supported or planned. But lacked at least in Swift 2.1.1.

— Hoon H.

_______________________________________________
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


(Jacob Bandes-Storch) #20

Perhaps I was being too imprecise; I meant that *rebinding* self isn't
currently allowed. Incidentally, this is exactly what the proposal is
proposing to allow.

Jacob

···

On Wed, Jan 6, 2016 at 1:18 PM, Paul Cantrell <cantrell@pobox.com> wrote:

But “self” _is_ a reserved word, and that’s the whole reason that this
proposal is necessary in the first place. If “self” were just a normal
identifier, then “if let self = self” would work just as well as “if let
foo = foo” and there would be nothing to discuss.

The docs also say "The backticks are not considered part of the
identifier; `x` and x have the same meaning." Thus `self` and self should
have the same meaning.

Well, `flurtzle` and flurtzle would have the same meaning, but `self` is
an identifier whereas as self is a keyword, so they mean different things.
That is precisely what the backticks are for.

Assigning to `self` is the same as assigning to self, which intentionally
isn't allowed.

No, you’re creating a new identifier called “self” which shadows the old
one.

Consider this:

    let foo: Int? = 7
    if let foo = foo {
        print(foo + 1)
    }

There are two identifiers named foo, one optional, one not. Both are
declared with “let”, so neither can be assigned to. But the code works.
Why? Because “let foo = foo” doesn’t assign to the outer variable; it
creates a new one. If self were not a keyword, then it would work the same
as “foo” above.

Cheers,

Paul

On Jan 6, 2016, at 2:56 PM, Jacob Bandes-Storch via swift-evolution < > swift-evolution@swift.org> wrote:

Not exactly; backticks are for making an identifier out of something
that's not normally an identifier. Most other reserved words are used in
control flow & other declarations. Rarely do they actually represent
identifiers/values that you can work with.

The docs also say "The backticks are not considered part of the
identifier; `x` and x have the same meaning." Thus `self` and self should
have the same meaning. Assigning to `self` is the same as assigning to
self, which intentionally isn't allowed. Backticks shouldn't allow you to
circumvent that.

Jacob

On Wed, Jan 6, 2016 at 12:50 PM, Paul Cantrell <paul@innig.net> wrote:

Ummm … isn’t that _exactly_ what backticks are for? From the docs:

    To use a reserved word as an identifier, put a backtick (`) before
and after it.

On Jan 5, 2016, at 10:42 PM, Greg Parker via swift-evolution < >> swift-evolution@swift.org> wrote:

I think it is a bug :slight_smile: That's not what backquotes are for. It ought to
be either supported without the backquotes or banned regardless of
backquotes.

On Jan 5, 2016, at 8:34 PM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

Yes, it seems to use the strong shadowing variable. (The compiler doesn't
complain about "self.foo", and "self?.foo" becomes invalid because self is
no longer optional.)

If it weren't so useful, I'd call it a bug.

On Tue, Jan 5, 2016 at 8:34 PM, Greg Parker <gparker@apple.com> wrote:

Does further use of self after that actually use a strong shadowing
variable? Or does it go back to the weak reference it already had as if the
shadow were not there?

On Jan 5, 2016, at 8:26 PM, Jacob Bandes-Storch via swift-evolution < >>> swift-evolution@swift.org> wrote:

Wow! I didn't know that worked. It's a bit surprising, and perhaps not
intended. I think the proposal is still valid.

On Tue, Jan 5, 2016 at 8:21 PM, Christopher Rogers < >>> christorogers@gmail.com> wrote:

You can shadow self with a guard like you wrote it if use the keyword
escaping backquotes like so:

guard let `self` = self else { return }

_______________________________________________
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