[swift-evolution] Draft proposal: multi-property assignment .= operator

Jacob Bandes-Storch jtbandes at gmail.com
Mon Jan 11 02:32:00 CST 2016


I would much prefer to see something like a "with" construct, which has
been discussed previously in other threads. It would afford
property-setting and also method calls, allowing people to build DSLs
pretty easily. I don't feel that a multi-setter is particularly valuable as
a special case.

object.{      // or "with object {"
    property1 = 1
    property2 = "a"
    method()
    ...
}

Jacob Bandes-Storch

On Sun, Jan 10, 2016 at 12:21 PM, Michel Fortin via swift-evolution <
swift-evolution at swift.org> wrote:

> (This proposal came from thinking about the memberwise initializer
> proposal as well as older proposals for "cascading" and creating scopes
> making some members act like local variables.)
>
> I'd like to propose a syntax to set multiple properties at once. It would
> look like this:
>
>         var object = MyObject()
>         object .= (
>                 property1: 1,
>                 property2: "a"
>         )
>
> and be equivalent to this:
>
>         var object = MyObject()
>         object.property1 = 1
>         object.property2 = "a"
>
> What the `.=` operator does is take each value in the tuple on the right
> and assign them to the property of the same name on the variable on the
> left. Assignments are performed in the same order as they're defined in the
> tuple.
>
> The tuple on the left of the `.=` operator can be written on the spot (as
> above) or be the result of an arbitrary expression, like here:
>
>         var object = MyObject()
>
>         var values = (property1: 1, property2: "b")
>         object .= values
>
>         func makeValuesFor(value: Int) -> (property1: Int, property2:
> String) {
>                 return (value, "\(value)")
>         }
>         object .= makeValuesFor(4)
>
> If the tuple contains property names that do not exist in the assigned
> variable, or if there is a mismatch in type or visibility and the
> assignment cannot happen, this is a compile-time error.
>
> This syntax is particularly beneficial when assigning to properties of a
> deeply nested value:
>
>         object.subpart.detail.numberPad .= (
>                 radix: 9
>                 position: .Top
>                 font: .System
>         )
>
>
> ## Tentative Implementation
>
> It's almost possible already to implement this with reflection. Here's an
> attempt (using a different operator name because `.=` doesn't work as a
> custom operator):
>
>         infix operator ~= {  }
>
>         func ~= <T>(inout target: T, values: (a: Int, b: String)) {
>                 let valuesMirror = Mirror(reflecting: values)
>                 let targetMirror = Mirror(reflecting: target)
>                 valueLoop: for valueField in valuesMirror.children {
>                         guard let label = valueField.label else {
>                                 fatalError("Missing label in value tuple.")
>                         }
>                         for targetField in targetMirror.children {
>                                 print(targetField)
>                                 if targetField.label == label {
>                                         targetField.value =
> valueField.value
>                                         continue valueLoop
>                                 }
>                         }
>                 }
>         }
>
> This fails because you can't assign to fields using the Mirror API. If
> this line could be replaced by something that works:
>
>         targetField.value = valueField.value
>
> then we could have a library implementation.
>
>
> --
> Michel Fortin
> https://michelf.ca
>
> _______________________________________________
> 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/20160111/236f66df/attachment.html>


More information about the swift-evolution mailing list