[swift-evolution] [Review] SE-0018 Flexible Memberwise Initialization

Matthew Johnson matthew at anandabits.com
Thu Jan 7 17:11:37 CST 2016


> On Jan 7, 2016, at 3:31 PM, Kevin Ballard <kevin at sb.org> wrote:
> 
> On Thu, Jan 7, 2016, at 07:12 AM, Matthew Johnson wrote:
>>> As for my concern, it's with the following rule:
>>>  
>>>> If the initializer body assigns to a var property that received memberwise initialization synthesis report a warning. It is unlikely that overwriting the value provided by the caller is the desired behavior.
>>>  
>>> I understand why you put this in there, but this is a warning that cannot be suppressed and will make it impossible to use a memberwise initializer for perfectly legitimate cases where you do in fact want to mutate the property after it's been assigned to.
>>  
>> For normal initializers I agree with you.  However, I think it’s a reasonable for callers to assume that if you expose a property via memberwise initialization the post-initialization value will match the value they provide.  This warning is intended to alert you to the fact that you are violating that reasonable assumption.
>  
> I think that's a reasonable assumption in many cases, but I don't like the fact that the feature cannot be used at all in the rare case where it actually makes sense to mutate the value.
>  
>> Do you have an example of where you would want a caller to initialize a property, but then overwrite the value they provide during initialization?
>  
> Sure, how about something like a Rect type that always guarantees it's in "standard" form (e.g. no negative sizes):
>  
> struct StandardRect {
>     var origin: CGPoint
>     var size: CGSize {
>         didSet {
>             // ensure standardized form here
>         }
>     }
>     
>     memberwise init(...) {
>         if size.width < 0 {
>             origin.x += size.width
>             size.width = -size.width
>         }
>         if size.height < 0 {
>             origin.y += size.height
>             size.height = -size.height
>         }
>     }
> }

This is a good example.  Thanks!  

I think cases like this will be rare so I still think a warning is a good idea.  Something like -Wno-overwrite-memberwise-init would allow it to be suppressed in cases where you actually do intend to do this.  Would that satisfy you?

>  
> Or how about a struct that represents a URL request complete with headers, and forces the inclusion of Content-Type:
>  
> struct URLRequest {
>     var headers: [String: String] = [:]
>     // ... other properties here ...
>     memberwise init(contentType: String, ...) {
>         headers["Content-Type"] = contentType
>     }
> }
>  
> -Kevin Ballard

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


More information about the swift-evolution mailing list