[swift-evolution] [Pitch] mutable `newValue` in willSet

Xiaodi Wu xiaodi.wu at gmail.com
Mon Sep 12 01:03:00 CDT 2016


I've run up against this too and had a similar thought. But on reflection I
think the current "workaround" is actually the superior solution.

Even though in your example it's very clear that newValue is being mutated,
if newValue were mutable, it would be possible to *accidentally* mutate it
without warning or error if you are calling certain methods on newValue
instead of using an assignment operator. For instance, in other contexts,
I've made such a mistake more than once with array.append() when array is
mutable, and I can never quite remember which of popFirst, dropFirst, etc.,
is a non-mutating term-of-art and which is mutating.

Of course, this can happen with any mutable value, but in all other
circumstances you actually write "var something", whereas in your proposal
you never have to write "var newValue". In fact, what you're actually
proposing isn't even the equivalent of "var newValue"; it's to have
newValue be of type `inout T` instead of `T`. I think such an implicit
inout has no precedent in Swift and would be confusing to users.

By contrast, I think the current solution is very clear and hard to make a
mistake with, although it is a little wordy.

On Sun, Sep 11, 2016 at 10:50 PM Karl via swift-evolution <
swift-evolution at swift.org> wrote:

> Sometimes you would like to modify the value being set to a property
> before it is set.
>
> Currently, you would have to add a separate backing property and implement
> the getter and setter, even if you want to perform a simple bounds-check on
> the value being set and want to cap it to allowed values.
>
> e.g:
>
> var bounds : Bounds {
>     willSet {
>       // Cap the bounds
>       newValue = newValue.capped(to: maximumSize)
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>     }
>
>     didSet {
>       // Load the new bounds
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>     }
> }
>
> Against the workaround you have to do currently:
>
> var _bounds : Bounds
> var bounds : Bounds {
>     get { return _bounds }
>     set {
>       // Cap the bounds
>       _bounds = newValue.capped(to: maximumSize)
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>
>       // Load the new bounds
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>       // Some comments to demonstrate noise if we were doing more
> processing
>     }
> }
>
> Currently, the capping in willSet is a compile-time error because
> `newValue` is a let constant, but I find that breaking your accessor code
> up in to willSet/didSet blocks allows for greater readability, especially
> when you have lots of processing to do (in the workaround example, the
> validation/preprocessing code and effects/postprocessing code are only
> separated by a comment). I propose that, at least for the scope of willSet
> (and *not* didSet, if we can manage that), that the variable should be
> mutable.
>
> Any thoughts?
>
> Karl
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160912/0b8ec571/attachment.html>


More information about the swift-evolution mailing list