Re: [swift-evolution] Rules for structs default/memberwise initializers

2017-02-15 Thread Dimitri Racordon via swift-evolution
Thanks Matthew.

That’s a quite elaborated proposal!
I’ll be sure to keep an eye on it as we move forward.

Dimitri



On 15 Feb 2017, at 16:57, Matthew Johnson 
> wrote:

Hi Dimitri,

You may be interested in taking a look at a proposal I introduced about a year 
ago which was deferred.  Memberwise initialization is a topic we intend to 
revisit eventually.  This may happen in phase 2 of the Swift 4 effort, or may 
not happen until Swift 5.

https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md

Matthew

On Feb 15, 2017, at 9:38 AM, Dimitri Racordon via swift-evolution 
> wrote:

Hello community!

While writing a Swift introduction tutorial for students, I’ve been stumbling 
upon the rules for struct default and memberwise initializers.
I failed to find explanations in Apple’s language guide, but as far as I could 
observe, I think the rules don’t fit interesting use-cases.

Here are the cases that I was able to identify (I hope you don’t mind 
millennials and their obligatory Pokemon references):

First, as documented in Apple’s guide, structs that doesn’t define any 
initializer and have no default values receive a memberwise initializer:

typealias Species = (number: Int, name: String)

struct Pokemon {
let species: Species
var level: Int
var nickname: String
}

let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")

Structs that define a default value for all their properties receive a default 
initializer:

struct Pokemon {
let species: Species = (001, "Bulbasaur")
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon()

Now digging a bit deeper, I noticed that they also seem to receive an 
initializer for their non-constant properties:

let bulby = Pokemon(level: 1, nickname: "bulby")

If no value is provided for one (or several) of its variable properties, they 
receives an initializer for all their variable properties:

struct Pokemon {
let species: Species = (001, "Bulbasaur")
var level: Int = 1
var nickname: String
}

let bulby = Pokemon(level: 1, nickname: "bulby")

Finally, if they're given a default value for their variable properties but not 
for their constant properties, they receive the full memberwise initializer 
only:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")

If the two extreme cases sounds perfectly valid to me (no default value vs all 
default values), the mixed situations do not.
In particular, it seems strange that a struct without a default value for its 
constant property, but one for all its variable properties receives the 
memberwise initializer only. I guess that would be a common “mixed situation” 
case, yet the provided initializer is actually useless.

Receiving the full memberwise initializer is fine, but I would also expect to 
receive some kind of "partial memberwise” initializer for all properties 
(constants or variables) that are not defined:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon(species: (001, "Bulbasaur”))
print(bulby)
// Prints "Pokemon(species: (1, "Bulbasaur"), level: 1, nickname: "bulby")"

Besides, that would avoid some tedious initializer definitions. Indeed, If I 
want to get the desired result, I have to write this kind of initializer:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"

init(species: Species, level: Int? = nil, nickname: String? = nil) {
self.species = species

if level != nil {
self.level = level!
}

if nickname != nil {
self.nickname = nickname!
}
}
}

In addition to be rather wordy, it arguably destroys the purpose of defining a 
default value for variable properties in the first place, since imho this 
approach is clearer (unless maybe for some more complicated structs with 
multiple layers of initializer delegation):

struct Pokemon {
let species: Species
var level: Int
var nickname: String

init(species: Species, level: Int = 1, nickname: String = "bulby") {
self.species = species
self.level = level
self.nickname = nickname
}
}

Thanks.

Dimitri Racordon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Rules for structs default/memberwise initializers

2017-02-15 Thread Matthew Johnson via swift-evolution
Hi Dimitri,

You may be interested in taking a look at a proposal I introduced about a year 
ago which was deferred.  Memberwise initialization is a topic we intend to 
revisit eventually.  This may happen in phase 2 of the Swift 4 effort, or may 
not happen until Swift 5.

https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md

Matthew

> On Feb 15, 2017, at 9:38 AM, Dimitri Racordon via swift-evolution 
>  wrote:
> 
> Hello community!
> 
> While writing a Swift introduction tutorial for students, I’ve been stumbling 
> upon the rules for struct default and memberwise initializers.
> I failed to find explanations in Apple’s language guide, but as far as I 
> could observe, I think the rules don’t fit interesting use-cases.
> 
> Here are the cases that I was able to identify (I hope you don’t mind 
> millennials and their obligatory Pokemon references):
> 
> First, as documented in Apple’s guide, structs that doesn’t define any 
> initializer and have no default values receive a memberwise initializer:
> 
> typealias Species = (number: Int, name: String)
> 
> struct Pokemon {
> let species: Species
> var level: Int
> var nickname: String
> }
> 
> let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")
> 
> Structs that define a default value for all their properties receive a 
> default initializer:
> 
> struct Pokemon {
> let species: Species = (001, "Bulbasaur")
> var level: Int = 1
> var nickname: String = "bulby"
> }
> 
> let bulby = Pokemon()
> 
> Now digging a bit deeper, I noticed that they also seem to receive an 
> initializer for their non-constant properties:
> 
> let bulby = Pokemon(level: 1, nickname: "bulby")
> 
> If no value is provided for one (or several) of its variable properties, they 
> receives an initializer for all their variable properties:
> 
> struct Pokemon {
> let species: Species = (001, "Bulbasaur")
> var level: Int = 1
> var nickname: String
> }
> 
> let bulby = Pokemon(level: 1, nickname: "bulby")
> 
> Finally, if they're given a default value for their variable properties but 
> not for their constant properties, they receive the full memberwise 
> initializer only:
> 
> struct Pokemon {
> let species: Species
> var level: Int = 1
> var nickname: String = "bulby"
> }
> 
> let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")
> 
> If the two extreme cases sounds perfectly valid to me (no default value vs 
> all default values), the mixed situations do not.
> In particular, it seems strange that a struct without a default value for its 
> constant property, but one for all its variable properties receives the 
> memberwise initializer only. I guess that would be a common “mixed situation” 
> case, yet the provided initializer is actually useless.
> 
> Receiving the full memberwise initializer is fine, but I would also expect to 
> receive some kind of "partial memberwise” initializer for all properties 
> (constants or variables) that are not defined:
> 
> struct Pokemon {
> let species: Species
> var level: Int = 1
> var nickname: String = "bulby"
> }
> 
> let bulby = Pokemon(species: (001, "Bulbasaur”))
> print(bulby)
> // Prints "Pokemon(species: (1, "Bulbasaur"), level: 1, nickname: "bulby")"
> 
> Besides, that would avoid some tedious initializer definitions. Indeed, If I 
> want to get the desired result, I have to write this kind of initializer:
> 
> struct Pokemon {
> let species: Species
> var level: Int = 1
> var nickname: String = "bulby"
> 
> init(species: Species, level: Int? = nil, nickname: String? = nil) {
> self.species = species
> 
> if level != nil {
> self.level = level!
> }
> 
> if nickname != nil {
> self.nickname = nickname!
> }
> }
> }
> 
> In addition to be rather wordy, it arguably destroys the purpose of defining 
> a default value for variable properties in the first place, since imho this 
> approach is clearer (unless maybe for some more complicated structs with 
> multiple layers of initializer delegation):
> 
> struct Pokemon {
> let species: Species
> var level: Int
> var nickname: String
> 
> init(species: Species, level: Int = 1, nickname: String = "bulby") {
> self.species = species
> self.level = level
> self.nickname = nickname
> }
> }
> 
> Thanks.
> 
> Dimitri Racordon
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Rules for structs default/memberwise initializers

2017-02-15 Thread Dimitri Racordon via swift-evolution
Hello community!

While writing a Swift introduction tutorial for students, I’ve been stumbling 
upon the rules for struct default and memberwise initializers.
I failed to find explanations in Apple’s language guide, but as far as I could 
observe, I think the rules don’t fit interesting use-cases.

Here are the cases that I was able to identify (I hope you don’t mind 
millennials and their obligatory Pokemon references):

First, as documented in Apple’s guide, structs that doesn’t define any 
initializer and have no default values receive a memberwise initializer:

typealias Species = (number: Int, name: String)

struct Pokemon {
let species: Species
var level: Int
var nickname: String
}

let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")

Structs that define a default value for all their properties receive a default 
initializer:

struct Pokemon {
let species: Species = (001, "Bulbasaur")
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon()

Now digging a bit deeper, I noticed that they also seem to receive an 
initializer for their non-constant properties:

let bulby = Pokemon(level: 1, nickname: "bulby")

If no value is provided for one (or several) of its variable properties, they 
receives an initializer for all their variable properties:

struct Pokemon {
let species: Species = (001, "Bulbasaur")
var level: Int = 1
var nickname: String
}

let bulby = Pokemon(level: 1, nickname: "bulby")

Finally, if they're given a default value for their variable properties but not 
for their constant properties, they receive the full memberwise initializer 
only:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby")

If the two extreme cases sounds perfectly valid to me (no default value vs all 
default values), the mixed situations do not.
In particular, it seems strange that a struct without a default value for its 
constant property, but one for all its variable properties receives the 
memberwise initializer only. I guess that would be a common “mixed situation” 
case, yet the provided initializer is actually useless.

Receiving the full memberwise initializer is fine, but I would also expect to 
receive some kind of "partial memberwise” initializer for all properties 
(constants or variables) that are not defined:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"
}

let bulby = Pokemon(species: (001, "Bulbasaur”))
print(bulby)
// Prints "Pokemon(species: (1, "Bulbasaur"), level: 1, nickname: "bulby")"

Besides, that would avoid some tedious initializer definitions. Indeed, If I 
want to get the desired result, I have to write this kind of initializer:

struct Pokemon {
let species: Species
var level: Int = 1
var nickname: String = "bulby"

init(species: Species, level: Int? = nil, nickname: String? = nil) {
self.species = species

if level != nil {
self.level = level!
}

if nickname != nil {
self.nickname = nickname!
}
}
}

In addition to be rather wordy, it arguably destroys the purpose of defining a 
default value for variable properties in the first place, since imho this 
approach is clearer (unless maybe for some more complicated structs with 
multiple layers of initializer delegation):

struct Pokemon {
let species: Species
var level: Int
var nickname: String

init(species: Species, level: Int = 1, nickname: String = "bulby") {
self.species = species
self.level = level
self.nickname = nickname
}
}

Thanks.

Dimitri Racordon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution