indirect enums and structs - swift

To start off, I want to say that I'm aware there are many articles and questions within SO that refer to the indirect keyword in Swift.
The most popular explanation for the usage of indirect is to allow for recursive enums.
Rather than just knowing about what indirect allows us to do, I would like to know how it allows us to use recursive enums.
Questions:
Is it because enums are value types and value types do not scale well if they are built in a recursive structure? Why?
Does indirect modify the value type behaviour to behave more like a reference type?
The following two examples compile just fine. What is the difference?
indirect enum BinaryTree<T> {
case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}
enum BinaryTree<T> {
indirect case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}

The indirect keyword introduces a layer of indirection behind the scenes.
You indicate that an enumeration case is recursive by writing indirect before it, which tells the compiler to insert the necessary layer of indirection.
From here
The important part of structs and enums is that they're a constant size. Allowing recursive structs or enums directly would violate this, as there would be an indeterminable number of recursions, hence making the size non constant and unpredictable. indirect uses a constant size reference to refer to a constant size enum instance.
There's a different between the two code snippets you show.
The first piece of code makes BinaryTree<T> stored by a reference everywhere it's used.
The second piece of code makes BinaryTree<T> stored by a reference only in the case of node. I.e. BinaryTree<T> generally has its value stored directly, except for this explicitly indirect node case.

Swift indirect enum
Since Swift v2.0
Swift Enum[About] is a value type[About], and we assign it the value is copied that is why the size of type should be calculated at compile time.
Problem with associated value
enum MyEnum { //Recursive enum <enum_name> is not marked
case case1(MyEnum) `indirect`
}
it is not possible to calculate the final size because of recursion
Indirect says to compiler to store the associated value indirectly - by reference(instead of value)
indirect enum - is stored as reference for all cases
indirect case - is stored as reference only for this case
Also indirect is not applied for other value types(struct)

You can use indirect enum. It's not exactly struct, but it is also a value type. I don't think struct has similar indirect keyword support.
From Hacking with Swift post:
Indirect enums are enums that need to reference themselves somehow, and are called “indirect” because they modify the way Swift stores them so they can grow to any size. Without the indirection, any enum that referenced itself could potentially become infinitely sized: it could contain itself again and again, which wouldn’t be possible.
As an example, here’s an indirect enum that defines a node in a linked list:
indirect enum LinkedListItem<T> {
case endPoint(value: T)
case linkNode(value: T, next: LinkedListItem)
}
Because that references itself – because one of the associated values is itself a linked list item – we need to mark the enum as being indirect.

Related

When exactly do I need "indirect" with writing recursive enums?

I'm surprised to find out that this compiles:
enum Foo {
case one([Foo])
// or
// case one([String: Foo])
}
I would have expected the compiler to tell me to add indirect to the enum cases, as Foo contains more Foos. Arrays and Dictionarys are all value types, so there are no indirection here. To me, this is structurally similar to this:
enum Foo {
case one(Bar<Foo>)
}
// arrays and dictionaries are just a struct with either something or nothing in it
// right?
struct Bar<T> {
let t: T?
}
... which does require me to add indirect to the enum.
Then I tried tuples:
enum Foo {
case one((Foo, Foo))
}
and this is considered a recursive enum too. I thought arrays and tuples have the same memory layout, and that is why you can convert arrays to tuples using withUnsafeBytes and then binding the memory...
What rules does this follow? Are there actually something special about arrays and dictionaries? If so, are there other such "special" types that looks like it should require indirect, but actually doesn't?
The Swift Guide is not very helpful. It just says:
A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases. You indicate that an enumeration case is recursive by writing indirect before it, which tells the compiler to insert the necessary layer of indirection.
What "has another instance of the enumeration" means is rather vague. It is even possible to interpret it to mean that case one(Bar<Foo>) is not recursive - the case only has an instance of Bar<Foo>, not Foo.
I think part of the confusion stems from this assumption:
I thought arrays and tuples have the same memory layout, and that is why you can convert arrays to tuples using withUnsafeBytes and then binding the memory...
Arrays and tuples don't have the same memory layout:
Array<T> is a fixed-size struct with a pointer to a buffer which holds the array elements contiguously* in memory
Contiguity is promised only in the case of native Swift arrays [not bridged from Objective-C]. NSArray instances do not guarantee that their underlying storage is contiguous, but in the end this does not have an effect on the code below.
Tuples are fixed-size buffers of elements held contiguously in memory
The key thing is that the size of an Array<T> does not change with the number of elements held (its size is simply the size of a pointer to the buffer), while a tuple does. The tuple is more equivalent to the buffer the array holds, and not the array itself.
Array<T>.withUnsafeBytes calls Array<T>.withUnsafeBufferPointer, which returns the pointer to the buffer, not to the array itself. *(In the case of a non-contiguous bridged NSArray, _ArrayBuffer.withUnsafeBufferPointer has to create a temporary contiguous copy of its contents in order to return a valid buffer pointer to you.)
When laying out memory for types, the compiler needs to know how large the type is. Given the above, an Array<Foo> is statically known to be fixed in size: the size of one pointer (to a buffer elsewhere in memory).
Given
enum Foo {
case one((Foo, Foo))
}
in order to lay out the size of Foo, you need to figure out the maximum size of all of its cases. It has only the single case, so it would be the size of that case.
Figuring out the size of one requires figuring out the size of its associated value, and the size of a tuple of elements is the sum of the size of the elements themselves (taking into account padding and alignment, but we don't really care about that here).
Thus, the size of Foo is the size of one, which is the size of (Foo, Foo) laid out in memory. So, what is the size of (Foo, Foo)? Well, it's the size of Foo + the size of Foo... each of which is the size of Foo + the size of Foo... each of which is the size of Foo + the size of Foo...
Where Array<Foo> had a way out (Array<T> is the same size regardless of T), we're stuck in an infinite loop with no base case.
indirect is the keyword required to break out of the recursion and give this infinite reference a base case. It inserts an implicit pointer by making a given case the fixed size of a pointer, regardless of what it contains or points to. That makes the size of one fixed, which allows Foo to have a fixed size.
indirect is less about Foo referring to Foo in any way, and more about allowing an enum case to potentially contain itself indirectly (because direct containment would lead to an infinite loop).
As an aside, this is also why a struct cannot contain a direct instance of itself:
struct Foo {
let foo: Foo // error: Value type 'Foo' cannot have a stored property that recursively contains it
}
would lead to infinite recursion, while
struct Foo {
let foo: UnsafePointer<Foo>
}
is fine.
structs don't support the indirect keyword (at least in a struct, you have more direct control over storage and layout), but there have been pitches for adding support for this on the Swift forums.
Indirect on enum cases can be used to tell the compiler to store the associated value of that enum as a pointer. Reference.
This is necessary when the compiler couldn't figure out the memory layout of the associated value without using a pointer, such as in the case of recursive enums.
The reason why you need to make the below case indirect is because by using a generic struct that holds your enum as an associated value on a case of the enum itself, you end up with a recursive enum, since you can nest Foo and Bar in each other infinitely many times.
enum MaybeRecursive {
case array([MaybeRecursive])
case dict([String: MaybeRecursive])
indirect case genericStruct(GenericStruct<MaybeRecursive>)
}
struct GenericStruct<T> {
let t: T?
}
// if you replaced `.array` with `.genericStruct` again, you could keep going forever
let associatedValue = GenericStruct(t: MaybeRecursive.genericStruct(.init(t: .array([]))))
MaybeRecursive.genericStruct(associatedValue)
As for the Array vs Tuple difference, Itai Ferber has expertly explained that part in their own answer.

How am I able to change this constant? [duplicate]

I'm really new to Swift and I just read that classes are passed by reference and arrays/strings etc. are copied.
Is the pass by reference the same way as in Objective-C or Java wherein you actually pass "a" reference or is it proper pass by reference?
Types of Things in Swift
The rule is:
Class instances are reference types (i.e. your reference to a class instance is effectively a pointer)
Functions are reference types
Everything else is a value type; "everything else" simply means instances of structs and instances of enums, because that's all there is in Swift. Arrays and strings are struct instances, for example. You can pass a reference to one of those things (as a function argument) by using inout and taking the address, as newacct has pointed out. But the type is itself a value type.
What Reference Types Mean For You
A reference type object is special in practice because:
Mere assignment or passing to function can yield multiple references to the same object
The object itself is mutable even if the reference to it is a constant (let, either explicit or implied).
A mutation to the object affects that object as seen by all references to it.
Those can be dangers, so keep an eye out. On the other hand, passing a reference type is clearly efficient because only a pointer is copied and passed, which is trivial.
What Value Types Mean For You
Clearly, passing a value type is "safer", and let means what it says: you can't mutate a struct instance or enum instance through a let reference. On the other hand, that safety is achieved by making a separate copy of the value, isn't it? Doesn't that make passing a value type potentially expensive?
Well, yes and no. It isn't as bad as you might think. As Nate Cook has said, passing a value type does not necessarily imply copying, because let (explicit or implied) guarantees immutability so there's no need to copy anything. And even passing into a var reference doesn't mean that things will be copied, only that they can be if necessary (because there's a mutation). The docs specifically advise you not to get your knickers in a twist.
Everything in Swift is passed by "copy" by default, so when you pass a value-type you get a copy of the value, and when you pass a reference type you get a copy of the reference, with all that that implies. (That is, the copy of the reference still points to the same instance as the original reference.)
I use scare quotes around the "copy" above because Swift does a lot of optimization; wherever possible, it doesn't copy until there's a mutation or the possibility of mutation. Since parameters are immutable by default, this means that most of the time no copy actually happens.
It is always pass-by-value when the parameter is not inout.
It is always pass-by-reference if the parameter is inout. However, this is somewhat complicated by the fact you need to explicitly use the & operator on the argument when passing to an inout parameter, so it may not fit the traditional definition of pass-by-reference, where you pass the variable directly.
Here is a small code sample for passing by reference.
Avoid doing this, unless you have a strong reason to.
func ComputeSomeValues(_ value1: inout String, _ value2: inout Int){
value1 = "my great computation 1";
value2 = 123456;
}
Call it like this
var val1: String = "";
var val2: Int = -1;
ComputeSomeValues(&val1, &val2);
The Apple Swift Developer blog has a post called Value and Reference Types that provides a clear and detailed discussion on this very topic.
To quote:
Types in Swift fall into one of two categories: first, “value types”,
where each instance keeps a unique copy of its data, usually defined
as a struct, enum, or tuple. The second, “reference types”, where
instances share a single copy of the data, and the type is usually
defined as a class.
The Swift blog post continues to explain the differences with examples and suggests when you would use one over the other.
When you use inout with an infix operator such as += then the &address symbol can be ignored. I guess the compiler assumes pass by reference?
extension Dictionary {
static func += (left: inout Dictionary, right: Dictionary) {
for (key, value) in right {
left[key] = value
}
}
}
origDictionary += newDictionaryToAdd
And nicely this dictionary 'add' only does one write to the original reference too, so great for locking!
Classes and structures
One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference.
Closures
If you assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles
ARC(Automatic Reference Counting)
Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.
Classes are passed by references and others are passed by value in default.
You can pass by reference by using the inout keyword.
Swift assign, pass and return a value by reference for reference type and by copy for Value Type
[Value vs Reference type]
If compare with Java you can find matches:
Java Reference type(all objects)
Java primitive type(int, bool...) - Swift extends it using struct
struct is a value type so it's always passed as a value. let create struct
//STEP 1 CREATE PROPERTIES
struct Person{
var raw : String
var name: String
var age: Int
var profession: String
// STEP 2 CREATE FUNCTION
func personInformation(){
print("\(raw)")
print("name : \(name)")
print("age : \(age)")
print("profession : \(profession)")
}
}
//allow equal values
B = A then call the function
A.personInformation()
B.personInformation()
print(B.name)
it have the same result when we change the value of 'B' Only Changes Occured in B Because A Value of A is Copied, like
B.name = "Zainab"
a change occurs in B's name. it is Pass By Value
Pass By Reference
Classes Always Use Pass by reference in which only address of occupied memory is copied, when we change similarly as in struct change the value of B , Both A & B is changed because of reference is copied,.

Recursive Enumerations in Swift

I'm learning Swift 2 (and C, but also not for long) for not too long and I came to a point where I struggle a lot with recursive enumerations.
It seems that I need to put indirect before the enum if it is recursive. Then I have the first case which has Int between the parentheses because later in the switch it returns an Integer, is that right?
Now comes the first problem with the second case Addition. There I have to put ArithmeticExpression between the parentheses. I tried putting Int there but it gave me an error that is has to be an ArithmeticExpression instead of an Int. My question is why? I can't imagine anything what that is about. Why can't I just put two Ints there?
The next problem is about ArithmeticExpression again. In the func solution it goes in an value called expression which is of the type ArithmeticExpression, is that correct? The rest is, at least for now, completely clear. If anyone could explain that to me in an easy way, that'd be great.
Here is the full code:
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
}
func solution(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value1):
return value1;
case . Addition(let value1, let value2):
return solution(value1)+solution(value2);
}
}
var ten = ArithmeticExpression.Number(10);
var twenty = ArithmeticExpression.Number(20);
var sum = ArithmeticExpression.Addition(ten, twenty);
var endSolution = solution(sum);
print(endSolution);
PeterPan, I sometimes think that examples that are TOO realistic confuse more than help as it’s easy to get bogged down in trying to understand the example code.
A recursive enum is just an enum with associated values that are cases of the enum's own type. That's it. Just an enum with cases that can be set to associated values of the same type as the enum. #endof
Why is this a problem? And why the key word "indirect" instead of say "recursive"? Why the need for any keyword at all?
Enums are "supposed" to be copied by value which means they should have case associated values that are of predictable size - made up of cases with the basic types like Integer and so on. The compiler can then guess the MAXIMUM possible size of a regular enum by the types of the raw or associated values with which it could be instantiated. After all you get an enum with only one of the cases selected - so whatever is the biggest option of the associated value types in the cases, that's the biggest size that enum type could get on initialisation. The compiler can then set aside that amount of memory on the stack and know that any initialisation or re-assignment of that enum instance could never be bigger than that. If the user sets the enum to a case with a small size associated value it is OK, and also if the user sets it to a case with the biggest associated value type.
However as soon as you define an enum which has a mixture of cases with different sized associated types, including values that are also enums of the same type (and so could themselves be initialised with any of the enums cases) it becomes impossible to guess the maximum size of the enum instance. The user could keep initialising with a case that allows an associated value that is the same type as the enum - itself initialised with a case that is also the same type, and so on and so on: an endless recursion or tree of possibilities. This recursion of enums pointing to enums will continue until an enum is initialised with associated value of "simple" type that does not point to another enum. Think of a simple Integer type that would “terminate” the chain of enums.
So the compiler cannot set aside the correct sized chunk of memory on the stack for this type of enum. Instead it treats the case associated values as POINTERS to the heap memory where the associated value is stored. That enum can itself point to another enum and so on. That is why the keyword is "indirect" - the associated value is referenced indirectly via a pointer and not directly by a value.
It is similar to passing an inout parameter to a function - instead of the compiler copying the value into the function, it passes a pointer to reference the original object in the heap memory.
So that's all there is to it. An enum that cannot easily have its maximum size guessed at because it can be initialised with enums of the same type and unpredictable sizes in chains of unpredictable lengths.
As the various examples illustrate, a typical use for such an enum is where you want to build-up trees of values like a formula with nested calculations within parentheses, or an ancestry tree with nodes and branches all captured in one enum on initialisation. The compiler copes with all this by using pointers to reference the associated value for the enum instead of a fixed chunk of memory on the stack.
So basically - if you can think of a situation in your code where you want to have chains of enums pointing to each other, with various options for associated values - then you will use, and understand, a recursive enum!
The reason the Addition case takes two ArithmeticExpressions instead of two Ints is so that it could handle recursive situations like this:
ArithmeticExpression.Addition(ArithmeticExpression.Addition(ArithmeticExpression.Number(1), ArithmeticExpression.Number(2)), ArithmeticExpression.Number(3))
or, on more than one line:
let addition1 = ArithmeticExpression.Addition(ArithmeticExpression.Number(1), ArithmeticExpression.Number(2))
let addition2 = ArithmeticExpression.Addition(addition1, ArithmeticExpression.Number(3))
which represents:
(1 + 2) + 3
The recursive definition allows you to add not just numbers, but also other arithmetic expressions. That's where the power of this enum lies: it can express multiple nested addition operations.

Need clarification on Enumeration types in Swift

I am trying to understand Enumerations in Swift but I am confused about the assignment to a variable. Here is an example:
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
var myPlanet = Planet.Mercury
I am confused about the last line. Is myPlanet variable being assigned a Planet object with case Mercury as its value?
It's not really a Planet "Object" because Swift prefers the term "Type". An "Object" implies that it's an instance of a "class." Classes, enums & structs in Swift sort of blur the lines a bit vs. other languages.
Planet is not a class, but an enumeration - a collection of related "member values". You're literally counting or "enumerating" all the various options within the group, and saying what name each one should go by. This provides a helpful alias to each value, allowing you to refer to the planets by name, instead of saying "Planet #1, #2, #3, #4, #5..."
Any situation where you have a finite collection of equal options may be a good candidate for an enum: "North, South, East, West" is another common example.
What you're doing here is declaring a new variable myPlanet, and assigning its initial value to the Planet enum's member value Mercury. The Planet Type is not explicitly declared, but is inferred from context - this new variable must be of Type Planet in order to hold the desired value of .Mercury.
An alternative declaration would be: var myPlanet: Planet = .Mercury
By explicitly declaring the Type of the var to be a Planet you can omit Planet from the righthand side.
Also, since it's a var & not let you could later change myPlanet to any of the "member values" of the Planet enum. Since myPlanet can only be 1 of the possible Planet options, you only need to refer to the member value:
myPlanet = .Earth
You could not, however, change myPlanet to a different Type (whether enum, struct, or class), because its type was already defined as Planet.
See the Enumerations chapter of the Swift Programming Language Guide for more examples/details (though this example is the same, so you're probably reading it).
EDIT BASED ON COMMENTS:
To me Planet.Mercury means an enumeration type called Planet with only case Mercury inside of it.
Your myPlanet variable is of Type Planet, with only the value .Mercury assigned to it. "Planet.Mercury" as a statement is like pointing to "Menu of Planets, Value: Mercury."
A basic enum is a list of possible options, like a menu:
List of Planets to Choose From
1. Mercury
2. Venus
3. Earth
4. etc...
The variable myPlanet is a container that can only have 1 value at a time.
Since you set it to 1 of the options listed within the Planet enum definition, Swift infers that it must be of Type Planet. From that point forward, this container is marked "Only For Planets" and its assigned value can only come from the enum list. The Planet enum itself is static - it's the restaurant menu and always contains the same options (unless you edit the enum definition itself).
If I were to write it in terms of a class called Planet, I see it as myPlanet = Planet(name: "Mercury"). Do you have an analogy that can help me grasp the enumeration concept? – Walter
With the class example, you'd be using a method to initialize a Planet instance with a property name that you set to the String "Mercury". This is different in a number of ways. For one, "name" in this case is a property of Type String, which has getter/setter methods, etc. You could presumably set name to whatever you want: Planet.name = "Walter" You also have to access the property by its name, and provide it with a value. This is not true of enums.
With an enum, all you have is the predefined list of possible options.
Mercury, Venus, Earth, Mars, etc. The enum's "member values" are simply nicknames, similar to an alias for "Entry #1, Entry #2, Entry #3". If "Planet.Walter" is not in the predefined list, you cannot assign a variable of Type Planet to that value. It knows it has to be a Planet but it won't find case Walter among the options.
Also, the reason I am still confused has to do with accessing computed properties inside the enumeration. For example, if I had a computed property called size that is based on self inside the enumeration based on, the way to access is myPlanet.size. This means that it is equivalent to Planet.Mercury.size. How am I accessing a computed property through the case >value Mercury?
Computed properties are one of the places where Swift blurs the lines of traditional Object-Oriented Programming, because they exist in classes, enums, and structs, so it can get confusing.
myPlanet.size doesn't necessarily equal Planet.Mercury.size - it could be Planet.size where size is a computed property returned from a function within the enum itself.
See this question for an example:
Swift Tour Card.createDeck() Returning [{(enum value), (enum value)}]
The following is an untested variation on the card deck example:
enum Planet {
case Mercury, Venus, Earth, Mars
func size() -> String {
switch self {
case .Mercury:
return "pretty darn small!"
case .Venus:
return "still small!"
case .Earth:
return "we think this is normal"
case .Mars:
return "slightly bigger than Earth"
}
}
}
var myPlanet: Planet = .Mercury
print(\myPlanet.size()) //"pretty darn small!"
myPlanet = .Mars
print(\myPlanet.size()) //"slightly bigger than Earth"
With this approach, the "size" function is a method of the Planet enum, similar to how an object can have instance methods, or a struct can have methods too. Calling myPlanet.size() after assigning a value is like saying "I'm a Type Planet, so if I look at myself, I know I'm a Mercury, so when I execute this method I have because I'm a Planet, I return the value for Mercury." Change the assigned value, and the method remains the same, but the returned value is now different, because myPlanet now has a different value.
I wouldn't say it is an object that you're assigning to myPlanet. You're assigning myPlanet with Mercury, which is a member of the enumeration Planet. Apple's documentation states:
If you are familiar with C, you will know that C enumerations assign related names to a set of integer values. Enumerations in Swift are much more flexible, and do not have to provide a value for each member of the enumeration. If a value (known as a “raw” value) is provided for each enumeration member, the value can be a string, a character, or a value of any integer or floating-point type.
They go on to elaborate on this further (answering your question, in my opinion):
The values defined in an enumeration (such as North, South, East, and West) are the member values (or members) of that enumeration. The case keyword indicates that a new line of member values is about to be defined.
NOTE
Unlike C and Objective-C, Swift enumeration members are not assigned a default integer value when they are created. In the CompassPoint example above, North, South, East and West do not implicitly equal 0, 1, 2 and 3. Instead, the different enumeration members are fully-fledged values in their own right, with an explicitly-defined type of CompassPoint.
You're not entirely wrong in thinking of the assigned value as an object, though – as the documentation continues with:
Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes, such as computed properties to provide additional information about the enumeration’s current value, and instance methods to provide functionality related to the values the enumeration represents. Enumerations can also define initializers to provide an initial member value; can be extended to expand their functionality beyond their original implementation; and can conform to protocols to provide standard functionality.
Swift enumerations do not work the same way as in Objective C.
The values which are stored inside of them cannot be used on their own (unless the type can be inferred). In the example below type can be inferred:
var myPlanet:Planet = .Mercury
First you are telling compiler that the variable is of type Planet and then you can use shorthand notation.
Apple's documentation is pretty good on enumerations and I strongly encourage you to read it:

Strange behaviour for recursive enum in Swift (Beta 7)

enum Tree{
case Leaf(String)
case Node(Tree)
} //compiler not happy!!
enum Tree{
case Leaf(String)
case Node([Tree])
} //compiler is happy in (arguably) a more complex recursive scenario?
How can the Swift compiler work for the second (more complex) scenario and not the first?
It is worth noting that Swift 2 beta 2 and further has indirect keyword for recursive enum - that means
enum Tree<T> {
case Leaf(T)
indirect case Node(Tree)
}
is valid language construct that doesn't break pattern matching in Swift 2.
TL;DR of the decision: "[…] we decided that the right solution is to simply not support general, non-obvious recursion through enums, and require the programmer to mediate that explicitly with indirect."
A value type (an enum) cannot contain itself as a direct member, since not matter how big a data structure is, it cannot contain itself. Apparently associated data of enum cases are considered direct members of the enum, so the associated data cannot be the type of the enum itself. (Actually, I wish that they would make recursive enums work; it would be so great for functional data structures.)
However, if you have a level of indirection, it is okay. For example, the associated data can be an object (instance of a class), and that class can have a member that is the enum. Since class types are reference types, it is just a pointer and does not directly contain the object (and thus the enum), so it is fine.
The answer to your question is: [Tree] does not contain Tree directly as a member. The fields of Array are private, but we can generally infer that the storage for the elements of the array are not stored in the Array struct directly, because this struct has a fixed size for a given Array<T>, but the array can have unlimited number of elements.
Chris Lattner (designer of Swift) says on the Apple Developer forums that autoclosure
has emerged as a way to "box" expression value in a reference (e.g.
working around limitations with recursive enums).
However, the following code (which works in Swift 1.1) does not work in Swift 1.2 that comes with Xcode Beta Version 6.3 (6D520o). The error message is "Attributes can only be applied to declarations, not types", however if this is intended, I don't know how to reconcile it with Lattner's statement about the behaviour he talks about in the previous quote as being "a useful thing, and we haven't removed it with Swift 1.2."
enum BinaryTree {
case Leaf(String)
case Node(#autoclosure () -> BinaryTree, #autoclosure () -> BinaryTree)
}
let l1 = BinaryTree.Leaf("A")
let l2 = BinaryTree.Leaf("B")
let l3 = BinaryTree.Leaf("C")
let l4 = BinaryTree.Leaf("D")
let n1 = BinaryTree.Node(l1, l2)
let n2 = BinaryTree.Node(l3, l4)
let t = BinaryTree.Node(n1, n2)