Hey, Milos! Can you please give us a few real-world examples where initializing a nontrivial tree-like data structure in code would be useful?
It's an honest question — I have never felt the need in my life, and I always preferred to move the data into something like a bundled json or CSV, rather than providing it in code. A. > On Apr 14, 2016, at 10:27 PM, Milos Rankovic via swift-evolution > <swift-evolution@swift.org> wrote: > > In Swift, we cannot compile: > > _ = [[], 1, [2, 3], [[4, 5], [6, 7], [8, 9]]] > > The reason for the compile-time error is that we are not in fact creating an > array, but a tree – a more general structure of which arrays are only a > special case. Given the well-deserved and growing reputation of Swift, one > would hope that in this instance the compiler would be able to default to > something like a: > > enum Tree<Value> { > case Leaf(Value) > case Branches([Tree]) > } > > extension Tree : ArrayLiteralConvertible { > init(arrayLiteral elements: Tree...) { > self = .Branches(elements) > } > } > > For this to work in the playground, however, we must manually lift the values > into the world of trees first. And to make that chore in turn easier on the > eye we can introduce a: > > prefix operator ◊ {} // looks a bit like a leaf (us/uk kbd: ⎇⇧V) > prefix func ◊ <T> (leaf: T) -> Tree<T> { return .Leaf(leaf) } > > let tree: Tree<Int> = [[], ◊1, [◊2, ◊3], [[◊4, ◊5], [◊6, ◊7], [◊8, ◊9]]] > > The point here is that if adding such a fundamental type to the Standard > Library would not be a priority at present, it is not the end of the world > since we can easily enough write it ourselves… What we cannot do ourselves, > however, is to get rid of the need for that operator in the common scenario > of initialising with literal values. For this we need a literal-convertible > protocol requiring two initialisers: > > protocol TreeLiteralConvertible { > associatedtype LeafValue > init(literal: Self.LeafValue...) > init(literal: Self...) > } > > Then we could simply: > > let tree: Tree<Int> = [[], 1, [2, 3], [[4, 5], [6, 7], [8, 9]]] > > And, whilst we are at it, we could also get rid of the need for that operator > in the case of nested associative arrays (again, you can try this in the > playground): > > enum DictionaryTree<Key, Value> { > case Leaf(Value) > case Branches([(Key, DictionaryTree)]) > } > > extension DictionaryTree : DictionaryLiteralConvertible { > init(dictionaryLiteral pairs: (Key, DictionaryTree)...) { > self = .Branches(pairs) > } > } > > prefix func ◊ <Key, Value> (leaf: Value) -> DictionaryTree<Key, Value> { > return .Leaf(leaf) } > > let map: DictionaryTree<String,Int> = [ > "A" : [:], > "B" : [ > "Ba" : ◊0, > "Bb" : ◊0, > "Bc" : [ > "Bc1" : ◊0, > "Bc2" : ◊0, > "Bc3" : ◊0 > ] > ] > ] > > … by introducing an analogous protocol: > > protocol DictionaryTreeLiteralConvertible { > associatedtype Key > associatedtype LeafValue > init(literal: Self.LeafValue...) > init(literal: (Key, Self)...) > } > > Please note: I do understand that fleshing out these structures (along with > all the juicy methods, operators and lazy alternatives) may not currently be > a priority for Swift. The two literal-convertible protocols however, may be a > much less daunting task, which would open to us some very useful programming > idioms… > > milos > _______________________________________________ > 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