Well, actually we can compile :

var zz : [Any] = [[Int](), 1,  [2, 3], [[4, 5], [6, 7], [8, 9]]]

[] - is empty array of unknown type, I think this is why you can't compile.

We need good language tools to process such kind of array, I agree with you.

As for your proposal.. I have no idea if this all is used often and can make our life easier. Probably some other can provide us with opinion.

On 14.04.2016 19:27, Milos Rankovic via swift-evolution 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])
}

extensionTree : 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:

prefixoperator ◊ {} // looks a bit like a leaf (us/uk kbd: *⎇⇧*V)
prefixfunc ◊ <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:

protocolTreeLiteralConvertible {
associatedtypeLeafValue
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):

enumDictionaryTree<Key, Value> {
case Leaf(Value)
case Branches([(Key, DictionaryTree)])
}

extensionDictionaryTree : DictionaryLiteralConvertible {
init(dictionaryLiteral pairs: (Key, DictionaryTree)...) {
self = .Branches(pairs)
}
}

prefixfunc ◊ <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:

protocolDictionaryTreeLiteralConvertible {
associatedtypeKey
associatedtypeLeafValue
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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to