[swift-evolution] [Proposal Draft] Flexible memberwise initialization

Tino Heth 2th at gmx.de
Fri Jan 1 06:57:38 CST 2016


>> I deny that, and even if it is true, there is a price to pay — and that is more than the lines of code that are required…
> 
> Personally, I think it is a lot more readable to put members separate lines, but if you don’t like doing that:
You are focusing on the least important thing here — I basically meant to say that the lower line count is no real benefit, but that there are advantages that aren't as easy to spot.

>>> 1. It interacts well with access control
>> Better than Kotlin? Please prove this.
> 
> Please look at the examples I have in the Access Control section of the proposal.  I spent some time reading the Kotlin docs and it isn’t clear to me that Kotlin can do this.  But maybe it can.  I don’t know Kotlin well.  It sounds like you do, so if it can, please show how this is done in Kotlin.
I actually don't know Kotlin that well — and that contributes to my evaluation of their solution: It is intuitive, and I did not have to read a huge article to understand it.
What I can see in your example is that the proposed syntax allows me to trigger compiler errors that will never happen with Kotlin (and errors that cannot happen are the ones I like the most).

>>> 2. Partial memberwise initialization is possible
>> The same with Kotlin — and imho at least as easy
> 
> That isn’t clear from the Kotlin docs.  It may well be that they are just missing examples.  Please post some samples showing how this is handled.
see below; of course, the sample won't use memberwise initialization, but archive the same in a (imho) better way

>>> 3. It allows memberwise initializers to accept non-memberwise parameters to initialize private state
>> I think this can be achieved with less effort using function-like class declaration (afair Joe already gave an example)
> 
> I don’t see either of the examples Joe posted doing this.  Here is an example showing what I mean:
> 
> struct S {
>     let s: String
>     private let i: Int
> 
>     // user declares:
>     memberwise init(other: S, ...) {
>         i = other.i
>     }
>     // compiler synthesizes (suppressing memberwise initialization for properties with lower visibility):
>     init(other: S, s: String) {
>         /* synthesized */ self.s = s
> 
>         // body of the user's initializer remains
>         i = other.i
>     }
> }


Instead of several examples, I'll use just a single one to illustrate a bunch of points — and I'm leaving out comments on purpose, because I hope to see others participating with their interpretation:

public class Customer(title: String, private var birthday: NSDate?, public address: String = "n/a"): Person {

	protected let statusPoints = - birthday?.timeIntervalSinceNow() ?? 0.0

	let constantWithHardToExpressValue: Int

	lazy var age: Int = dateCalculationIsHard(birthday)

	init {
		constantWithHardToExpressValue = Int(statusPoints) + 1
		super.init(title: title)
	}
	
	public init(titlePrefix: String, titleSuffixObject: Any) {
		init(title: titlePrefix + titleSuffixObject.description, birthday: NSDate())
	}
}

So: Dear reader, please do my job and explain the "pseudo"-source above ;-) — or ask questions if you are just puzzled by it.

>>> 4. More than one memberwise initializer is possible
>> Kotlin has no need for memberwise initializers at all, and I see this as a big advantage
> 
> Please explain how it is an advantage.  How does Kotlin handle a case where you have some private state that needs to be initialized internally to protect invariants, but also some members which users can initialize (such as appearance attributes on a UI widget)?
For me, something that is not necessary is always an advantage — because you can simply remove it and have a result that is more elegant and compact.
Why would you want to add a feature that is not needed? It's just more work for those who actually build it, and it's more work for those who have to learn how to use it.

>> 
>>> 5. Memberwise initialization of properties with declaration modifiers, behaviors / delegates is possible
>> https://kotlinlang.org/docs/reference/delegated-properties.html <https://kotlinlang.org/docs/reference/delegated-properties.html>
>> (afaik this is not only possible, it's handled by the current compiler for a long time)
> 
> Yes, I know Kotlin has this feature.  It isn’t clear from the docs how initialization of such properties is handled (for example an Observable property).  Maybe you can provide some examples of how this works.
No, I can't (well, I accidentally did it partly...) — but I don't see why I should prove the features of a system that actually exists (and where everyone can easily check the behavior):
I think it's not that presumptuous to assume that the Kotlin-compiler has no flaws which are so fundamental.

>> Afaics there not much room left for the promised additional flexibility… and the problem with default values for constants just doesn't exist in Kotlin at all.
> 
> This is currently a problem in Swift.  I am confident that it can be solved one way or another.  I don’t think a solution should be tied to the “type initializer parameter list” syntax.
As I said before:
There is no need to copy, but there is also no need to discard a working solution without further explanation.

> If you can clearly demonstrate how Kotlin is superior in a specific area I will give that great consideration.  I want this proposal to be the best it can be.  However, you’re going to need to do more than just link to the docs which I have already looked at.
I see it from the other direction:
You have a "theory" (the proposal) and claim it is sound; Kotlin, on the other hand, is real working code!

> The good news is that as far as I can tell the things you like about what Kotlin is doing are not mutually exclusive with this proposal at all.  Think of it this way - this proposal provides a flexible and orthogonal foundation for memberwise initialization.  If desired, a future enhancement could easily be developed to provide additional syntactic sugar on top of it.  The example Joe posted shows how that might work.  
> 
> If this proposal is accepted and you want to pursue a proposal for that additional layer of syntactic sugar to get closer to Kotlin syntax I encourage you to do that.  The new syntax should be evaluated independently as its own proposal.  I would be happy to help show how your desired syntax could be transformed into existing syntax (including the memberwise initialization syntax if this proposal is accepted).
I guess you really want to see your proposals accepted — and I understand that, as I'm quite sure that you put a huge amount of work into them.
But a "let's just take my solution and maybe integrate yours laterl"-attitude imho is not the right way:
If it is used to silence opposers without actually supporting them later, it is wily; and if it is a honest offer, we'll end up with a language that is extrem complicated because it tries to please everyone (and orthogonality would suffer as well).

Best regards,
Tino
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160101/3349d563/attachment.html>


More information about the swift-evolution mailing list