struct Person {

   let age: Int
   let name: String
   let hobbies: [String]
   
   // Main initializer that takes all parameters directly and assigns values to (initializes) all properties above
   init(name: String, age: Int, hobbies: [String]) {
       self.name = name
       self.age = age
       self.hobbies = hobbies
   }
   
   // Convenience initializer
   // This initializer is convenient for whoever is trying to create a person from an Alien
   // It's more convenient to write:
   // let person = Person(alien: alien)
   // instead of:
   // let person = Person(name: alien.name, age: alien.age, hobbies: alien.hobbies) 
   // especially if you have to do this in multiple places.
   init(alien: Alien) {
       // This is delegating the initialization to the main initializer 
       // so if things change you dont risk forgetting to also update all convenience initializers
       self.init(name: alien.name , age: alien.age, hobbies: alien.hobbies)
   }
   
   // "Initializer delegation helps avoid duplication of code"
   // You avoid the duplication (and potentially having to update in multiple places) by calling self.init(...)
   // from inside a convenience initializer like the example above.
   init(alien: Alien) {
       // This is not preferred as it causes duplication with the main init
       self.name = alien.name
       self.age = alien.age
       self.hobbies = alien.hobbies
   }

}