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

Paul Cantrell cantrell at pobox.com
Fri Jan 8 21:25:12 CST 2016

> On Jan 8, 2016, at 5:41 PM, Matthew Johnson <matthew at anandabits.com> wrote:
>> On Jan 8, 2016, at 4:14 PM, Paul Cantrell <cantrell at pobox.com <mailto:cantrell at pobox.com>> wrote:
>>> Would you propose removing the current implicit memberwise initializer for structs on the same grounds?
>> No, it’s a much smaller feature surface. I would proposed promoting it from a simple, situational feature to something very generic — much like what Joe Groff is doing with “lazy.”
> How exactly would you do this?  I don’t understand what you think that would look like.

It would like what I sketched out in remainder of my previous message.

> Making it more capable is what my proposal is attempting to do so I am confused by this statement.

Making it more capable is not what I’m talking about. Making it more generic and more flexible it is what I’m talking about. 

The property behaviors proposal, at least as I understand it, could change “lazy” from being a language feature to being a library feature. In the language, lazy is replaced with something more flexible and generic, something that could give rise to other new features totally unrelated to laziness, but built from the same new building blocks.

The “memberwise” proposal, on the other hand, would be analogous to expanding the “lazy” feature at the language level, adding a bunch of new rules and behavior to it.

• • •

Based on your feedback, I’m not sure the central point of my review came across. I don’t think I can explain it better than I did in the review, but maybe others can find the words.

>> Here’s a sketch of that — not a proposal, total BS syntax, totally hypothetical:
>>     struct S {
>>         let s0, s1, s2: String
>>         private let i: Int
>>         init(anInt: Int, anotherInt: Int, otherArgs: Members.except(i)) {
>>             members = otherArgs  // assigned members inferred from tuple item names
>>             i = anInt > anotherInt ? anInt : anotherInt
>>         }
>>     }
>> I’d be happy — happier! — with a solution like that, despite the modest additional keystrokes, because (1) members and Members would presumably have a more predictable behavior that’s easier to remember and to understand by reading, and (2) they’d be usable in other contexts:
>>     mutating func updateFrom(other: S) {
>>         self.members = other.except(i)
>>         i = anInt > anotherInt ? anInt : anotherInt
>>     }
>> …or heck, even this:
>>     mutating func updateTwoStrings(s0: String, s1: String) {
>>         members = arguments
>>     }
>>     mutating func updateTwoStrings(s0: String, s1: String, message: String) {
>>         print(message)
>>         members = arguments.except(message)
>>     }
>> OK, I concede I'm now brainstorming quite a feature list here:
>> members property that turns all (stored?) properties into a tuple,
>> Members property that returns the type of the above,
>> select / except operations on any tuple that create a new tuple by filtering keys,
>> assignment of a tuple to members that matches by tuple key (and the tuple can contain a subset of all properties),
>> some way of variadically expanding a tuple type in an arg list, and
>> arguments implicit variable that gives all func args as a tuple. (That last one’s not necessary to replace this proposal; just threw it in there because I’m brainstorming.)
>> That’s a lot! But all these feature are more independent, flexible, and transparent than the ones in the proposal. They (1) need not all be understood all at once, (2) have less implicit behavior and rules about corner cases, (3) thus have a simpler mental model and are easier to understand just by reading, and (4) provide more capabilities in a broader range of contexts.
> I really don’t think the “members” computed tuple property is a workable solution for initializing `let` properties.

What not? All the static type information is there for the compiler to apply the same checks it does right now.

> Any such property that was allowed to do so would not work outside an initializer anyway as it would try to mutate a `let` when you used it.

Well, yes, because instead of invisible magic, the “members = tuple” initialization behaves exactly like any other assignment.

> I have also been thinking a lot about approaches that would be similar in some sense and build on a general purpose parameter forwarding mechanism.  I have some ideas that I am going to work on fleshing out tonight.

That’s the sort of thing I’d be interested in seeing.



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

More information about the swift-evolution mailing list