[swift-evolution] [Proposal] Allow scoped properties from within computed properties

David Sweeris davesweeris at mac.com
Fri Jan 13 12:41:15 CST 2017


> On Jan 13, 2017, at 11:27, Joseph Newton via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi,
> 
> I've done a lot of Objective-C and have been been a fan of Swift since it's come out, however, there's a small feature of Objective-C that I would really like to see implemented in Swift:
> 
> In Objective-C you have a few options implementation-wise when creating properties for your class. You could use the @synthesize statement to have the compiler create the backing ivar along with the appropriate accessor methods or your could use the @dynamic statement to tell the compiler that you're going to create your own accessor methods and backing ivar (if needed).
> 
> Additionally, one could use the @synthesize statement to have the compiler create the backing ivar, and then they could create custom accessor methods to supply custom functionality or validation. I use this third case extensively in my Objecitve-C code but there's not a concise way of doing this in Swift.
> 
> For example, I might have an Objective-C implementation that looks like this:
> 
> @interface Foo : NSObject
> @property (nullable, copy) NSString *bar;
> @end
> 
> @implementation Foo
> @synthesize bar = _bar; // Creates ivar '_bar'
> 
> - (void)setBar:(NSString *)bar {
>     if (bar.length < 100)
>         _bar = nil;
>     else
>         _bar = [bar copy];
> }
> 
> @end
> 
> Currently, the only way to implement this in Swift - AFAIK - is as follows:
> 
> class Foo {
>     private var _bar: String?
>     public var bar: String? {
>         get { return _bar }
>         set {
>             if (newValue?.characters.count ?? 0) < 100 {
>                 _bar = nil
>             }
>             else {
>                 _bar = newValue.copy() as! String
>             }
>         }
>     }
> }
> 
> Although this works, it isn't exactly glamorous. The main drawback of this implementation (unless intended) is that you now have any additional '_bar' variable accessible within the scope of your class. 

I believe you can do this using didSet without the `_bar`:
class Foo {
    public var bar: String? {
        didSet {
            if (bar?.characters.count ?? 0) < 100 {
                bar = nil
            }
        }
    }
}


> My proposal is to allow stored properties in the declaration block of computed properties. For this example, the '_bar' declaration would simply be moved inside of the declaration block for 'bar':
> 
> class Foo {
>     public var bar: String? {
>         var _bar: String?
> 
>         get { return _bar }
>         set {
>             if (newValue?.characters.count ?? 0) < 100 {
>                 _bar = nil
>             }
>             else {
>                 _bar = newValue.copy() as! String
>             }
>         }
>     }
> }
> 
> Only the getter and setter methods of 'bar' are allowed to access and modify the stored '_bar' property. My proposal would also allow for multiple stored properties of varying types within the scope of a single computed property. This would also simply atomic synchronization for single variables:
> 
> class Foo {
>     static var synchronizedBar: String? {
>         var queue = DispatchQueue(label: "Foo.synchronizedBar")
>         var bar: String?
> 
>         get { return queue.sync { return bar } }
>         set { queue.sync { bar = newValue } }
>     }
> }
> 
> Are there any suggestions or arguments, for or against, for this proposal?

It's an interesting idea, for sure. Because of the persistent storage required for `_bar`, I think one way to look at what you're proposing is essentially as a way to allow for a variable to be declared publicly as one type, be implemented as another (anonymous, in this case) type under the hood, and to specify a mechanism for automatically converting between the two types.

- Dave Sweeris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170113/910f422c/attachment.html>


More information about the swift-evolution mailing list