[swift-evolution] [Proposal] Uniform Initialization Syntax

Gor Gyolchanyan gor at gyolchanyan.com
Thu Jun 8 10:27:46 CDT 2017


To clarify further about DefaultInitializable:

An uninitialized variable of a DefaultInitializable type will *only* have its `init()` called if it's accessed before being initialized manually. This will ensure that the variable will never be initialized twice.


> On Jun 8, 2017, at 6:20 PM, Gor Gyolchanyan <gor at gyolchanyan.com> wrote:
> 
> Yeah, it's just a small syntactic sugar that doesn't change the current behavior at all, it merely makes initialization syntax more uniform and consistent.
> 
> Also, something just occurred to me:
> 
> When we're dealing with convenience initializers, there's the syntax `self.init(...)`, wouldn't it be nice to be able to use the same general syntax to initializing members?
> The primary use case is to be able to avoid extra allocations and copies (especially for large structures).
> It would look a lot like constructors in C++, where you have an opportunity to directly initialize members in-place, except it won't be mandatory in case the member is not default-initializable.
> Here's an example of what I imagine it could look like:
> 
> init() {
> 	self.myHeavyDutyMember1.init(...)
> 	self.myHeavyDutyMember2.init(...)
> }
> 
> The rule would be that if a direct member initializer call is present in an initializer, no access to the member is allowed before that call and no other direct member initializer calls on the same member are allowed, even if the member is mutable.
> 
> Also also, something else just occurred to me:
> 
> Currently Optional and ImplicitlyUnwrappedOptional are the only default-initializable types in Swift and that's compiler magic.
> Wouldn't it be nice to have a DefaultInitializable protocol that the compiler would pick up on and treat the conforming type just like it does optionals? All the same initialization rules would apply.
> 
> protocol DefaultInitializable {
> 
> 	init()
> 
> }
> 
> An added benefit is how beautifully this would work with classes, where this will be a `required init`, meaning that subclasses will be forced to also be default-initializable, thus providing consistent polymorphic behavior that will make the initializability guarantees possible. 
> 
>> On Jun 8, 2017, at 6:00 PM, Charles Srstka <cocoadev at charlessoft.com> wrote:
>> 
>>> On Jun 8, 2017, at 9:19 AM, David Sweeris via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> #1 & #3 would violate Swift's rule about having to fully initialize all properties in inits.
>>> 
>>> My initial reaction is to like #2, though, assuming I understand it correctly.
>> 
>> Assigning things to self can already be done with structs and enums:
>> 
>> struct S {
>> 	let foo: String
>> 	
>> 	init(foo: String) {
>> 		self.foo = foo
>> 	}
>> 	
>> 	init(bar: String) {
>> 		self = S(foo: bar) // works fine
>> 	}
>> }
>> 
>> enum E {
>> 	case foo
>> 	case bar
>> 	
>> 	init(isFoo: Bool) {
>> 		if isFoo {
>> 			self = .foo // works fine
>> 		} else {
>> 			self = .bar // ditto
>> 		}
>> 	}
>> }
>> 
>> The one restriction is that in the case of the struct, you can’t have initialized any of the immutable properties before assigning to self.
>> 
>> struct S {
>> 	let foo: String
>> 	
>> 	init(foo: String) {
>> 		self.foo = foo
>> 	}
>> 	
>> 	init(bar: String) {
>> 		self.foo = "Foo"
>> 		self = S(foo: bar) // error: immutable value 'self.foo' may only be initialized once
>> 	}
>> }
>> 
>> The only real thing being proposed here, as I see it, is to make this behavior conceptually consistent with classes. Anything that simplifies the rather Byzantine rules surrounding initializers, while simultaneously enabling factory initializers, is a win in my book.
>> 
>> Charles
>> 
> 



More information about the swift-evolution mailing list