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

Reply via email to