How to access custom derive attributes? [duplicate] - macros

Serde supports applying custom attributes that are used with #[derive(Serialize)]:
#[derive(Serialize)]
struct Resource {
// Always serialized.
name: String,
// Never serialized.
#[serde(skip_serializing)]
hash: String,
// Use a method to decide whether the field should be skipped.
#[serde(skip_serializing_if = "Map::is_empty")]
metadata: Map<String, String>,
}
I understand how to implement a procedural macro (Serialize in this example) but what should I do to implement #[serde(skip_serializing)]? I was unable to find this information anywhere. The docs don't even mention this. I have tried to look at the serde-derive source code but it is very complicated for me.

First you must register all of your attributes in the same place you register your procedural macro. Let's say we want to add two attributes (we still don't talk what will they belong to: structs or fields or both of them):
#[proc_macro_derive(FiniteStateMachine, attributes(state_transitions, state_change))]
pub fn fxsm(input: TokenStream) -> TokenStream {
// ...
}
After that you may already compile your user code with the following:
#[derive(Copy, Clone, Debug, FiniteStateMachine)]
#[state_change(GameEvent, change_condition)] // optional
enum GameState {
#[state_transitions(NeedServer, Ready)]
Prepare { players: u8 },
#[state_transitions(Prepare, Ready)]
NeedServer,
#[state_transitions(Prepare)]
Ready,
}
Without that compiler will give a error with message like:
state_change does not belong to any known attribute.
These attributes are optional and all we have done is allow them to be to specified. When you derive your procedural macro you may check for everything you want (including attributes existence) and panic! on some condition with meaningful message which will be told by the compiler.
Now we will talk about handling the attribute! Let's forget about state_transitions attribute because it's handling will not vary too much from handling struct/enum attributes (actually it is only a little bit more code) and talk about state_change. The syn crate gives you all the needed information about definitions (but not implementations unfortunately (I am talking about impl here) but this is enough for handling attributes of course). To be more detailed, we need syn::DeriveInput, syn::Body, syn::Variant, syn::Attribute and finally syn::MetaItem.
To handle the attribute of a field you need to go through all these structures from one to another. When you reach Vec<syn:: Attribute> - this is what you want, a list of all attributes of a field. Here our state_transitions can be found. When you find it, you may want to get its content and this can be done by using matching syn::MetaItem enum. Just read the docs :) Here is a simple example code which panics when we find state_change attribute on some field plus it checks does our target entity derive Copy or Clone or neither of them:
#[proc_macro_derive(FiniteStateMachine, attributes(state_transitions, state_change))]
pub fn fxsm(input: TokenStream) -> TokenStream {
// Construct a string representation of the type definition
let s = input.to_string();
// Parse the string representation
let ast = syn::parse_derive_input(&s).unwrap();
// Build the impl
let gen = impl_fsm(&ast);
// Return the generated impl
gen.parse().unwrap()
}
fn impl_fsm(ast: &syn::DeriveInput) -> Tokens {
const STATE_CHANGE_ATTR_NAME: &'static str = "state_change";
if let syn::Body::Enum(ref variants) = ast.body {
// Looks for state_change attriute (our attribute)
if let Some(ref a) = ast.attrs.iter().find(|a| a.name() == STATE_CHANGE_ATTR_NAME) {
if let syn::MetaItem::List(_, ref nested) = a.value {
panic!("Found our attribute with contents: {:?}", nested);
}
}
// Looks for derive impls (not our attribute)
if let Some(ref a) = ast.attrs.iter().find(|a| a.name() == "derive") {
if let syn::MetaItem::List(_, ref nested) = a.value {
if derives(nested, "Copy") {
return gen_for_copyable(&ast.ident, &variants, &ast.generics);
} else if derives(nested, "Clone") {
return gen_for_clonable(&ast.ident, &variants, &ast.generics);
} else {
panic!("Unable to produce Finite State Machine code on a enum which does not drive Copy nor Clone traits.");
}
} else {
panic!("Unable to produce Finite State Machine code on a enum which does not drive Copy nor Clone traits.");
}
} else {
panic!("How have you been able to call me without derive!?!?");
}
} else {
panic!("Finite State Machine must be derived on a enum.");
}
}
fn derives(nested: &[syn::NestedMetaItem], trait_name: &str) -> bool {
nested.iter().find(|n| {
if let syn::NestedMetaItem::MetaItem(ref mt) = **n {
if let syn::MetaItem::Word(ref id) = *mt {
return id == trait_name;
}
return false
}
false
}).is_some()
}
You may be interested in reading serde_codegen_internals, serde_derive, serenity's #[command] attr, another small project of mine - unique-type-id, fxsm-derive. The last link is actually my own project to explain to myself how to use procedural macros in Rust.
After some Rust 1.15 and updating the syn crate, it is no longer possible to check derives of a enums/structs, however, everything else works okay.

You implement attributes on fields as part of the derive macro for the struct (you can only implement derive macros for structs and enums).
Serde does this by checking every field for an attribute within the structures provided by syn and changing the code generation accordingly.
You can find the relevant code here: https://github.com/serde-rs/serde/blob/master/serde_derive/src/internals/attr.rs

To expand Victor Polevoy's answer when it comes to the state_transitions attribute. I'm providing an example of how to extract the field attribute #[state_transitions(NeedServer, Ready)] on a enum that derives #[derive(FiniteStateMachine)]:
#[derive(FiniteStateMachine)]
enum GameState {
#[state_transitions(NeedServer, Ready)] // <-- extract this
Prepare { players: u8 },
#[state_transitions(Prepare, Ready)]
NeedServer,
#[state_transitions(Prepare)]
Ready,
}
use proc_macro::TokenStream;
#[proc_macro_derive(FiniteStateMachine, attributes(state_transitions))]
pub fn finite_state_machine(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();
// Extract the enum variants
let variants: Vec<&syn::Variant> = match &ast.data {
syn::Data::Enum(ref data_enum) => data_enum.variants.iter().collect(),
other => panic!("#[derive(FiniteStateMachine)] expects enum, got {:#?}", other)
};
// For each variant, extract the attributes
let _ = variants.iter().map(|variant| {
let attrs = variant.attrs.iter()
// checks attribute named "state_transitions(...)"
.find_map(|attr| match attr.path.is_ident("state_transitions") {
true => Some(&attr.tokens),
false => None,
})
.expect("#[derive(FiniteStateMachine)] expects attribute macros #[state_transitions(...)] on each variant, found none");
// outputs: attr: "(NeedServer, Ready)"
eprintln!("attr: {:#?}", attrs.to_string());
// do something with the extracted attributes
...
})
.collect();
...
}
The content of the extracted attrs (typed TokenStream) looks like this:
TokenStream [
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "NeedServer",
span: #0 bytes(5511..5521),
},
Punct {
ch: ',',
spacing: Alone,
span: #0 bytes(5521..5522),
},
Ident {
ident: "Ready",
span: #0 bytes(5523..5528),
},
],
span: #0 bytes(5510..5529),
},
]

Related

How do I compare two elements for equality in a Swift generic without knowing if they structs or class objects? [duplicate]

This question already has answers here:
How to compare "Any" value types
(7 answers)
Closed 20 days ago.
I have implemented a linked list in Swift. Code that uses this data structure can append, insert, etc., a new node into the list by providing an element of the generic type. In other words, the list holds nodes and each node holds a reference or instance of the type, and callers simply pass the T type element to insert into the list (not wasting lines of code creating a node they don't need to know about). Here are some pieces of the code defining the linked list (with tons of irrelevant stuff removed):
public class LinkedListNode<T> {
init( value: T ) {
self.value = value
}
public var next: LinkedListNode?
public weak var previous: LinkedListNode?
public var value: T
}
struct LinkedList<T>: Sequence {
internal var head: LinkedListNode<T>?
internal unowned var tail: LinkedListNode<T>?
#discardableResult public mutating func insert( _ value: T, after: LinkedListNode<T> ) -> LinkedListNode<T> {
if after === tail {
return append( value )
} else {
let node = LinkedListNode<T>( value: value )
insertBetween( node, after: after, before: after.previous )
return node
}
}
...
}
This all works great. I only had a medium amount of trouble finding documentation that explained how to make the Sequence protocol work right.
Now I want to add a function to add or replace an element in the list. I want the caller to pass in something of type T and I want to check to see if it exists so it can be replaced. I want to add the new element if it doesn't already exist. The problem is that I want to compare two T types to see if they are the same instance of an object of the list has objects in it (within the nodes) but compare for content equality if the list has structs or just native types like Int, within it.
I can do this outside of the linked list code because I have a first() function. Maybe that's a better choice. But I would still like to know if it's possible to write code that let's me do an appropriate equality test depending on the type of thing that the list contains.
This is what I was working on when I got to this problem:
#discardableResult public mutating func replaceOrAppend( _ value: T ) -> LinkedListNode<T> {
var node = first( where: { $0.value === value } )
if node == nil {
node = LinkedListNode<T>( value: value )
insertBetween( node!, after: tail, before: tail?.next )
tail = node
}
return node!
}
Notice that I used === for the comparison. Unless I define T as T:AnyObject, this will fail to compile. I want this to work to compare the content of structs and native types and the references for class objects.
Not all things can be compared for equality. Functions are a great example of this. If I have a LinkedList<() -> Void>, and I want to replaceOrAppend another () -> Void to it, how can you tell if the new function "already exists" in the linked list? Figuring that out would at least require solving the halting problem. :D
A better design would be to only have replaceOrAppend be available when T is Equatable:
extension LinkedList where T: Equatable {
// I've rewritten this to eliminate the "!"
#discardableResult public mutating func replaceOrAppend( _ value: T ) -> LinkedListNode<T> {
// now you can use "==", because T is known to be Equatable
if let node = first( where: { $0.value == value } ) {
return node
} else {
let newNode = LinkedListNode<T>( value: value )
insertBetween( newNode, after: tail, before: tail?.next )
tail = newNode
return newNode
}
}
}
The problem is that I want to compare two T types to see if they are the same instance of an object of the list has objects in it (within the nodes) but compare for content equality if the list has structs or just native types like Int, within it.
I don't think you should have this distinction. I would suggest you just use ==.
It's pretty unusual to have objects only be considered equal when they're exactly equal. If you callers did want that, they would implement Equatable/== to achieve that, or stuff it in a wrapper like the IdentityWrapper in this example here.

Get all components of entity

Is it possible to get a list of components by having Entity in bevy rust? For example for debugging purposes.
use bevy::prelude::*;
fn main()
{
App::build()
.add_plugins(DefaultPlugins)
.add_startup_system(setup.system())
.add_system(first.system())
.add_system(first_no_second.system())
.add_system(first_and_second.system())
.run()
}
fn setup(mut commands: Commands)
{
commands.spawn().insert(FirstComponent(0.0));
commands.spawn().insert(FirstComponent(1.0));
commands.spawn().insert(SecondComponent::StateA);
commands.spawn().insert(SecondComponent::StateB);
commands.spawn().insert(SecondComponent::StateA).insert(FirstComponent(3.0));
commands.spawn().insert(SecondComponent::StateB).insert(FirstComponent(4.0));
}
#[derive(Debug)]
struct FirstComponent(f32);
#[derive(Debug)]
enum SecondComponent
{
StateA,
StateB
}
fn first(query: Query<&FirstComponent>)
{
for entity in query.iter()
{
println!("First: {:?}", entity)
}
}
fn first_no_second(query: Query<&FirstComponent, Without<SecondComponent>>)
{
for entity in query.iter()
{
println!("First without Second: {:?}", entity)
}
}
fn first_and_second(query: Query<&FirstComponent, With<SecondComponent>>)
{
for entity in query.iter()
{
println!("First with Second: {:?}", entity)
}
}
How bevy's ecs understands which systems need to be started for a certain Queue. Within World, the components are somehow related to the Entity, am I right? Is it possible to somehow trace this connection from the outside? I really like how it works, for me it looks like magic, but I would like to understand what is happening "under the hood"
I found it possible to get direct access to the world, components and entities only through AppBuilder. Below is a sample code which is sufficient for my purposes
use bevy::prelude::*;
use bevy::ecs::component::{ComponentId, ComponentInfo};
fn main()
{
App::build()
.add_plugin(WorldPlugin::default())
.run()
}
// some components for test
struct TestComponent;
struct TestComponent2;
#[derive(Default)]
struct WorldPlugin {}
impl Plugin for WorldPlugin
{
fn build(&self, app: &mut AppBuilder)
{
// creating an entity with both test components
let entity = app.world_mut()
.spawn()
.insert(TestComponent)
.insert(TestComponent2)
.id();
// to interact with components and entities you need access to the world
let world = app.world();
// components are stored covertly as component id
for component_id in get_components_ids(world, &entity).unwrap()
{
let component_info = component_id_to_component_info(world, component_id).unwrap();
println!("{}", extract_component_name(component_info));
}
}
}
/// gets an iterator component id from the world corresponding to your entity
fn get_components_ids<'a>(world: &'a World, entity: &Entity) -> Option<impl Iterator<Item=ComponentId> + 'a>
{
// components and entities are linked through archetypes
for archetype in world.archetypes().iter()
{
if archetype.entities().contains(entity) { return Some(archetype.components()) }
}
None
}
fn component_id_to_component_info(world: &World, component_id: ComponentId) -> Option<&ComponentInfo>
{
let components = world.components();
components.get_info(component_id)
}
fn extract_component_name(component_info: &ComponentInfo) -> &str
{
component_info.name()
}
This code makes it possible to get a set of components for your entity, which allows you to get any data about a component. Here is a description of the ComponentInfo structure taken from the bevy source code
#[derive(Debug)]
pub struct ComponentInfo {
name: String,
id: ComponentId,
type_id: Option<TypeId>,
// SAFETY: This must remain private. It must only be set to "true" if this component is
// actually Send + Sync
is_send_and_sync: bool,
layout: Layout,
drop: unsafe fn(*mut u8),
storage_type: StorageType,
}
The world stores a set of components, entities, and "archetypes" are used to link them. An example diagram is attached below.

Is it possible to store pattern of enum with associated value in array?

Let's say we have simple enum with message types:
enum MessageType {
case audio
case photo
case text
}
There is Handler class which handles messages with specific types only:
class Handler {
let allowed: [MessageType]
init(_ allowed: [MessageType]) { self.allowed = allowed }
func canHandle(_ messageType: MessageType) -> Bool {
return allowed.contains(messageType)
}
}
Basic usage example:
let handler = Handler([.audio, .photo])
print(handler.canHandle(.text)) // Prints false
I want to upgrade my MessageType and add associated value for some of message types.
class Audio {}
enum MessageType {
case audio(Audio)
case photo
case text
}
Problem is that I can't store enum's pattern in allowed array for the future check in canHandle:
// error: '_' can only appear in a pattern or on the left side of an assignment
let handler = Handler([.audio(_), .photo])
Is it possible to resolve such case in a "clean" way?
It's not possible to modify MessageType because it's in third-party library (e.g. making arguments optional and passing nil)
It's not possible to init MessageType.audio(Audio) with fake Audio because it could have private initializer
I hope to avoid switch, case let or other hard-coded checks in canHandle
Any suggestions? Thanks
If instantiating the enum with a default (or garbage) value isn't a big deal
enum MessageType {
case audio(String)
case photo
case text
}
protocol SneakyEquatableMessage {
func equals(message: MessageType) -> Bool
}
extension MessageType: SneakyEquatableMessage {
func equals(message: MessageType) -> Bool {
switch (self, message) {
case (.audio(_), .audio(_)),
(.photo, .photo),
(.text, .text):
return true
default:
return false
}
}
}
class Handler {
let allowed: [MessageType]
init(_ allowed: [MessageType]) { self.allowed = allowed }
func canHandle(_ messageType: MessageType) -> Bool {
return allowed.contains { $0.equals(message: messageType) }
}
}
Basic Usage
let handler = Handler([.audio(""), .photo])
print(handler.canHandle(.text)) // Prints false
print(handler.canHandle(.audio("abc")) //Prints true
Default (or garbage) values are unrealistic
This particular section is more specific in this context, but ultimately you're going to have breakdown your enum somehow as of Swift 4. So this is my suggestion: Dependency Injection of the Factory Pattern inside Handler. This solves all of your problems pretty cleanly without having to touch switch within Handler or optionals.
enum DisassembledMessage {
case audio
case photo
case text
}
protocol MessageTypeFactory {
func disassemble(message: MessageType) -> DisassembledMessage
func disassemble(messages: [MessageType]) -> [DisassembledMessage]
}
class Handler {
let allowed: [MessageType]
let factory: MessageTypeFactory
init(allowed: [MessageType], with factory: MessageTypeFactory) {
self.allowed = allowed
self.factory = factory
}
func canHandle(_ messageType: DisassembledMessage) -> Bool {
return factory
.disassemble(messages: allowed)
.contains { $0 == messageType }
}
}
Basic Usage
let audioValue: Audio = //...
let audioMessage = MessageType.audio(audioValue)
let factory: MessageTypeFactory = //...
let handler = Handler(allowed: [audioMessage, .photo], with: factory)
print(handler.canHandle(.text)) // Prints false
print(handler.canHandle(factory.disassemble(message: audioMessage))) //Prints true
You may be asking: wait... you just created another enum (also this is just an example, you could convert it to whatever you want in that protocol). Well I say: the enum you're using is from a library... see my notes section. Also, you can now use that factory anywhere you need to break down the library type to something, including inside Handler. You could easily expand the protocol MessageTypeFactory to convert your enum to other types (hopefully behaviors) you've created, and basically just distance yourself from the library type when you need to. I hope this helps clarify what I was getting at! I don't even think you should store MessageType in your class. You should store your own type which is some kind of mapped version of MessageType, like DisassembledType.
I hope this helps!
Notes
A few things:
I'm sorry your soul is owned by a library, really.
Use the Adapter Pattern. Clean C++ is one of many places you
can learn about it. Don't pollute your entire code base with one of
their types! That's just a tip.
I know you said you didn't want to use a switch... but you're working with enums... At least it's within the enum!
Use your own types! (Did I say that?)
Use the Adapter Pattern! (Stop it.)

Optional Binding, Capturing References and Closures [possible bug]

I have been trying to get myself acquainted with Swift, but I recently came across this peculiar problem involving Optional Bindings and capturing references within the context of Closures.
Given the following declarations (code abbreviated for clarity; full code provided at the end):
class Thing
{
func giveNameIfSize() -> String? {
/.../
}
}
typealias IterationBlock = (Thing) -> Bool
class Iterable
{
func iterate(block: IterationBlock) {
/.../
}
}
An Iterable object can store a collection of Things and can iterate through them using a closure. Now say we wanted to find the name of the Thing object that has a size property set up. We could do something like this:
var name: String?
iterable.iterate { (someThing) -> Bool in
/*
Assigning the result of the giveNameIfSize() function to
a variable 'name' declared outside of the closure and
captured by reference
*/
if name = someThing.giveNameIfSize() {
return true
}
return false
}
However, the code above generates the following compiler error:
Cannot assign to immutable value of type 'String?'
Curiously enough, the problem disappears when we use another variable in the optional binding:
iterable.iterate { (someThing) -> Bool in
if var tempResult = someThing.giveNameIfSize() {
name = tempResult
return true
}
return false
} /* COMPILES AND RUNS */
The problem is also resolved if we assign a value to the externally declared variable name outside of the optional binding:
iterable.iterate { (someThing) -> Bool in
name = someThing.giveNameIfSize()
if name != nil {
return true
}
return false
} /* ALSO COMPILES AND RUNS */
Full source code here.
Obs.: Tested this code with Swift 1.2, not 2.0.
====
Is this a bug? Or am I missing something?
The error you're receiving is a little misleading, but the underlying problem here is that you're trying to do something that Swift doesn't support. In Swift, you can't use the result of assignment in a condition.
That being said, both of your proposed alternative methods will work, although I tend to think that the first of the two is a little more Swifty.

Generic Types Collection

Building on previous question which got resolved, but it led to another problem. If protocol/class types are stored in a collection, retrieving and instantiating them back throws an error. a hypothetical example is below. The paradigm is based on "Program to Interface not an implementation" What does it mean to "program to an interface"?
instantiate from protocol.Type reference dynamically at runtime
public protocol ISpeakable {
init()
func speak()
}
class Cat : ISpeakable {
required init() {}
func speak() {
println("Meow");
}
}
class Dog : ISpeakable {
required init() {}
func speak() {
println("Woof");
}
}
//Test class is not aware of the specific implementations of ISpeakable at compile time
class Test {
func instantiateAndCallSpeak<T: ISpeakable>(Animal:T.Type) {
let animal = Animal()
animal.speak()
}
}
// Users of the Test class are aware of the specific implementations at compile/runtime
//works
let t = Test()
t.instantiateAndCallSpeak(Cat.self)
t.instantiateAndCallSpeak(Dog.self)
//doesn't work if types are retrieved from a collection
//Uncomment to show Error - IAnimal.Type is not convertible to T.Type
var animals: [ISpeakable.Type] = [Cat.self, Dog.self, Cat.self]
for animal in animals {
//t.instantiateAndCallSpeak(animal) //throws error
}
for (index:Int, value:ISpeakable.Type) in enumerate(animals) {
//t.instantiateAndCallSpeak(value) //throws error
}
Edit - My current workaround to iterate through collection but of course it's limiting as the api has to know all sorts of implementations. The other limitation is subclasses of these types (for instance PersianCat, GermanShepherd) will not have their overridden functions called or I go to Objective-C for rescue (NSClassFromString etc.) or wait for SWIFT to support this feature.
Note (background): these types are pushed into array by users of the utility and for loop is executed on notification
var animals: [ISpeakable.Type] = [Cat.self, Dog.self, Cat.self]
for Animal in animals {
if Animal is Cat.Type {
if let AnimalClass = Animal as? Cat.Type {
var instance = AnimalClass()
instance.speak()
}
} else if Animal is Dog.Type {
if let AnimalClass = Animal as? Dog.Type {
var instance = AnimalClass()
instance.speak()
}
}
}
Basically the answer is: correct, you can't do that. Swift needs to determine the concrete types of type parameters at compile time, not at runtime. This comes up in a lot of little corner cases. For instance, you can't construct a generic closure and store it in a variable without type-specifying it.
This can be a little clearer if we boil it down to a minimal test case
protocol Creatable { init() }
struct Object : Creatable { init() {} }
func instantiate<T: Creatable>(Thing: T.Type) -> T {
return Thing()
}
// works. object is of type "Object"
let object = instantiate(Object.self) // (1)
// 'Creatable.Type' is not convertible to 'T.Type'
let type: Creatable.Type = Object.self
let thing = instantiate(type) // (2)
At line 1, the compiler has a question: what type should T be in this instance of instantiate? And that's easy, it should be Object. That's a concrete type, so everything is fine.
At line 2, there's no concrete type that Swift can make T. All it has is Creatable, which is an abstract type (we know by code inspection the actual value of type, but Swift doesn't consider the value, just the type). It's ok to take and return protocols, but it's not ok to make them into type parameters. It's just not legal Swift today.
This is hinted at in the Swift Programming Language: Generic Parameters and Arguments:
When you declare a generic type, function, or initializer, you specify the type parameters that the generic type, function, or initializer can work with. These type parameters act as placeholders that are replaced by actual concrete type arguments when an instance of a generic type is created or a generic function or initializer is called. (emphasis mine)
You'll need to do whatever you're trying to do another way in Swift.
As a fun bonus, try explicitly asking for the impossible:
let thing = instantiate(Creatable.self)
And... swift crashes.
From your further comments, I think closures do exactly what you're looking for. You've made your protocol require trivial construction (init()), but that's an unnecessary restriction. You just need the caller to tell the function how to construct the object. That's easy with a closure, and there is no need for type parameterization at all this way. This isn't a work-around; I believe this is the better way to implement that pattern you're describing. Consider the following (some minor changes to make the example more Swift-like):
// Removed init(). There's no need for it to be trivially creatable.
// Cocoa protocols that indicate a method generally end in "ing"
// (NSCopying, NSCoding, NSLocking). They do not include "I"
public protocol Speaking {
func speak()
}
// Converted these to structs since that's all that's required for
// this example, but it works as well for classes.
struct Cat : Speaking {
func speak() {
println("Meow");
}
}
struct Dog : Speaking {
func speak() {
println("Woof");
}
}
// Demonstrating a more complex object that is easy with closures,
// but hard with your original protocol
struct Person: Speaking {
let name: String
func speak() {
println("My name is \(name)")
}
}
// Removed Test class. There was no need for it in the example,
// but it works fine if you add it.
// You pass a closure that returns a Speaking. We don't care *how* it does
// that. It doesn't have to be by construction. It could return an existing one.
func instantiateAndCallSpeak(builder: () -> Speaking) {
let animal = builder()
animal.speak()
}
// Can call with an immediate form.
// Note that Cat and Dog are not created here. They are not created until builder()
// is called above. #autoclosure would avoid the braces, but I typically avoid it.
instantiateAndCallSpeak { Cat() }
instantiateAndCallSpeak { Dog() }
// Can put them in an array, though we do have to specify the type here. You could
// create a "typealias SpeakingBuilder = () -> Speaking" if that came up a lot.
// Again note that no Speaking objects are created here. These are closures that
// will generate objects when applied.
// Notice how easy it is to pass parameters here? These don't all have to have the
// same initializers.
let animalBuilders: [() -> Speaking] = [{ Cat() } , { Dog() }, { Person(name: "Rob") }]
for animal in animalBuilders {
instantiateAndCallSpeak(animal)
}