Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Brent Royal-Gordon via swift-evolution
> Aren’t JSON arrays and objects actually the same thing? They’re both 
> essentially just ordered dictionaries, with objects mapping keys to 
> properties, functions etc., while arrays are just a dictionary where the keys 
> are consecutive integer (or should be, as long as you don’t mess with them)

You're confusing JSON with JavaScript.

JSON is a wire format which includes support for certain, specific types: 
objects (basically, dictionaries with string keys and heterogenous values), 
arrays (with heterogenous values), strings, booleans, doubles, and nulls. JSON 
has nothing to say about how these things are represented in memory once 
they're parsed out of the wire format.

JavaScript is a language with a prototype-based object system and a literal 
syntax which happens to be a superset of JSON. The statements you make about 
how "arrays are just objects with consecutive integer keys" and so on are true 
of JavaScript arrays, but they have nothing to do with JSON, merely with how 
JSON is conventionally represented once it's read into JavaScript.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Milos Rankovic via swift-evolution
> On 15 Apr 2016, at 19:54, Haravikk  wrote:
> 
> While the original post is an interesting way to define this structure, I 
> think a specialised type is required to really capture this usefully.

Sure. I never meant it as a replacement. It was a response to someone’s 
challenge whether one could express a piece of JSON data as a literal using the 
two example tree enums. The two protocols I’m proposing, however, could be 
implemented by many different kind of tree types, some of which could just as 
well have properties that fit JSON perfectly. It would then be a joy 
instantiating short JSON snippets as literals.

Still, as John anticipated, I could get this to compile too (keeping in mind 
that the lift operator ◊ would disappear if we get the two proposed protocols):

let johnny: DictionaryTree =
[
"children": ◊["George", "Ann", "Percy"],
"phoneNumbers": ◊[
◊[
"type": ◊"home",
"number": ◊"212 555-1234"
],
◊[
"type": ◊"office",
"number": ◊"646 555-4567"
],
]
]

… where:

enum JSONValue {
case Text(String)
case Array([JSONValue])
indirect case Object(DictionaryTree)
}

milos










___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Haravikk via swift-evolution

> On 15 Apr 2016, at 16:48, John McCall via swift-evolution 
>  wrote:
>  The JSONValue type needs to be able to embed both JSON arrays and JSON 
> objects,

Aren’t JSON arrays and objects actually the same thing? They’re both 
essentially just ordered dictionaries, with objects mapping keys to properties, 
functions etc., while arrays are just a dictionary where the keys are 
consecutive integer (or should be, as long as you don’t mess with them), 
compilers will optimise them behind the scenes if they can, but there’s 
essentially no specific array type in Javascript, the array functions are just 
manipulating a dictionary in an array-like fashion.

Anyway, this is probably a reason why Swift dictionaries shouldn’t be used to 
implement a tree in this way, as they have no strict ordering, but the order of 
values in JSON is important, particularly when it comes to duplicate keys (the 
last always one takes precedence), and it’s technically okay to parse multiple 
duplicates values and combine them together if you want.


While the original post is an interesting way to define this structure, I think 
a specialised type is required to really capture this usefully.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Milos Rankovic via swift-evolution
> On 15 Apr 2016, at 08:24, Andrey Tarantsov  wrote:
>> On 14 Apr 2016, at 19:23, Andrey Tarantsov  wrote:
>> 
>> Can you please give us a few real-world examples… 
> 
> I can't think of any real use cases for the kind of literals you want, 
> though, hence the question. (And I don't think it's worth adding just for 
> computer science playground experiments alone.)

let example: Tree = 
[
"Don't Cha Wish Your Language Was Hot Like Me?",
[
"Is it hard to come up with good examples of tree literals?",
"Why is that? It’s trees we work with every day:",
[
"views",
"directories",
"decision trees"
],
"What if we can't come up with good examples because",
"our imagination is limited by our medium? What if",
"we can't think of it because we do not think like it?"
]
]

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread John McCall via swift-evolution
> On Apr 15, 2016, at 1:29 AM, Milos Rankovic  
> wrote:
>> On 15 Apr 2016, at 03:22, John McCall > > wrote:

>> Your JSON literal example is already pretty well modeled by simply making a 
>> JSONValue type that conforms to all the literal protocols.  It is completely 
>> unclear why you would even want to model this with some generic Tree 
>> structure. 
> Because JSON has the structure of a tree.  A dictionary of the type 
> `[String:AnyObject]` does not express that structure even if at run-time it 
> turns out that some of those any-objects are themselves dictionaries. 
> `Tree`, in contrast, precisely expresses the structure of 
> JSON objects.

No, it's actually a very strange way to model it.  The JSONValue type needs to 
be able to embed both JSON arrays and JSON objects, so if you represent a JSON 
object as a DictionaryTree, you'll end up with two different 
ways to represent { "x" : { "y" : 1 } }.  It's much better to use the "flat" 
representation of Dictionary and allow the JSONValue enum's 
natural recursiveness to express nested objects.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Milos Rankovic via swift-evolution
> On 15 Apr 2016, at 03:22, John McCall  wrote:
> 
> The heterogeneity that I'm referring to is the mix of sub-trees and leaves at 
> a single level.
… which is why I was making the point that that part of the heterogeneity 
problem is solved.

> Your JSON literal example is already pretty well modeled by simply making a 
> JSONValue type that conforms to all the literal protocols.  It is completely 
> unclear why you would even want to model this with some generic Tree 
> structure. 
Because JSON has the structure of a tree. A dictionary of the type 
`[String:AnyObject]` does not express that structure even if at run-time it 
turns out that some of those any-objects are themselves dictionaries. 
`Tree`, in contrast, precisely expresses the structure of 
JSON objects. `[String:JSONValue]` is flat so it is not worth talking about, 
whilst some dedicated `JSON` enum is just that, a dedicated type that is the 
symptom of a language incapable of representing things like `[1, [2]]` as such. 

You do have a good point about conforming JSONValue type to the 
literal-convertible protocols. That is important here because it reminds us 
that the question of converting Int and String values to JSONValue type in my 
example is a completely separate issue from my proposal. This in turn shows 
that the two tree literal-convertable protocols I’d love to see added to the 
Standard Library would be sufficient in all cases. For instance (assuming the 
code from my original post is already in the context):

enum JSONValue {
case Integer(Int)
case Text(String)
case URL(NSURL)

init(_ string: String) {
if let url = NSURL(string: string) {
self = .URL(url)
} else {
self = .Text(string)
}
}
}

extension JSONValue : UnicodeScalarLiteralConvertible {
init(unicodeScalarLiteral value: String) { self.init(value) }
}
extension JSONValue : ExtendedGraphemeClusterLiteralConvertible {
init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
}
extension JSONValue : StringLiteralConvertible {
init(stringLiteral value: String){ self.init(value) }
}

extension JSONValue : IntegerLiteralConvertible {
init(integerLiteral value: Int) { self = .Integer(value) }
}

let city: JSONValue = .Text("New York")

let johnny: DictionaryTree =
[
"name": ◊"Johnny Appleseed",
"age": ◊25,
"github": ◊"http://github.com/apple/swift-evolution;,
"address": [
"number": ◊21,
"street": ◊"2nd Street",
"city": ◊city
]
]

This is what we can do already (try it in the playground - even the url is read 
as a url). However, if we were also given the following protocol:

protocol DictionaryTreeLiteralConvertible {
associatedtype Key
associatedtype LeafValue
init(literal: Self.LeafValue...)
init(literal: (Key, Self)...)
}

… then the lifting of the JSONValue-s into the recursive world of trees would 
be done by the `init(literal: Self.LeafValue…)` and we would no longer need the 
lifting operator ◊.

Finally, it is worth mentioning that the two proposed protocols, 
TreeLiteralConvertible and DictionaryTreeLiteralConvertible, should be simple 
to implement, would not affect existing code, and would allow us to work with 
all kinds of trees and nested associative arrays with ease, safety and elegance 
we are growing accustomed to when programming in Swift.

milos


> On 15 Apr 2016, at 03:22, John McCall  wrote:
> 
>> On Apr 14, 2016, at 2:56 PM, Milos Rankovic > > wrote:
>> Hi John and Brent, 
>> 
>>> On 14 Apr 2016, at 22:22, John McCall >> > wrote:
>>> 
>>> multiple-conformance idea doesn't work
>> 
>> 
>> The idea is not multiple-conformance (or overloading), but multiple (two) 
>> initialisers required by the literal-convertible protocols:
>> 
>> protocol TreeLiteralConvertible {
>>  associatedtype LeafValue
>>  init(literal: Self.LeafValue...)
>>  init(literal: Self...)
>> }
>> 
>> … and:
>> 
>> protocol DictionaryTreeLiteralConvertible {
>>  associatedtype Key
>>  associatedtype LeafValue
>>  init(literal: Self.LeafValue...)
>>  init(literal: (Key, Self)...)
>> }
>> 
>>> Note that all of your examples rely not just on recursion but on 
>>> heterogeneous recursion
>> 
>> The crux of the matter is not heterogeneity in general, but of the leaf 
>> value in particular. This is what Brent is addressing. All my examples, save 
>> one, had a uniform leaf value type (even the Tree example).
> 
> The heterogeneity that I'm referring to is the mix of sub-trees and leaves at 
> a single level.
> 
>> The one exception is my second JSON example. There I did not post 

Re: [swift-evolution] TreeLiteralConvertible

2016-04-15 Thread Andrey Tarantsov via swift-evolution
Hey!

>> Can you please give us a few real-world examples where initializing a 
>> nontrivial tree-like data structure in code would be useful?
> 
> I suppose we always prefer to move *all* data into databases or files with 
> dedicated data formats, *including* arrays, strings, dictionaries, etc. Sure. 
> But it would be rather underwhelming if you could not also just instantiate 
> an array or a string from a literal.

> Likewise, I find it a little deflating that I cannot express a piece of JSON 
> in code. 
> 
> Given the *simplicity* of these structures, it seems it should not be beyond 
> Swift to represent them in code with ease and elegance. And to begin with, 
> all we need are those couple of protocols.


Did you just... sidestep the question? :-)

The reason we want dictionary and array literals is that because they're needed 
in the real code bases, everywhere, not just for the abstract beauty of the 
langauge. I can certainly list many specific use cases for both array and 
dictionary literals, with code examples.

I can't think of any real use cases for the kind of literals you want, though, 
hence the question. (And I don't think it's worth adding just for computer 
science playground experiments alone.)

And, FWIW, JSON objects can absolutely be represented in Swift as 
Dictionary. I even typealias that as JSONObject, and have a 
lot of code parsing and producing these. While TreeDictionary 
looks superficially safer, I doubt it's worth the trouble. But again, I'd like 
to be proven wrong; the burden is on you to present the use cases!

I'm appalled by the fascination of Swift community with JSONValue-like enums. 
They produce the most horrible code on the parsing side, and seem to be an 
academic experiment in type safety. See this framework for what I believe to be 
the right approach to dealing with JSON in Swift: 
https://github.com/ExpressiveSwift/ExpressiveCasting

A.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread John McCall via swift-evolution
> On Apr 14, 2016, at 2:56 PM, Milos Rankovic  
> wrote:
> Hi John and Brent, 
> 
>> On 14 Apr 2016, at 22:22, John McCall > > wrote:
>> 
>> multiple-conformance idea doesn't work
> 
> 
> The idea is not multiple-conformance (or overloading), but multiple (two) 
> initialisers required by the literal-convertible protocols:
> 
> protocol TreeLiteralConvertible {
>   associatedtype LeafValue
>   init(literal: Self.LeafValue...)
>   init(literal: Self...)
> }
> 
> … and:
> 
> protocol DictionaryTreeLiteralConvertible {
>   associatedtype Key
>   associatedtype LeafValue
>   init(literal: Self.LeafValue...)
>   init(literal: (Key, Self)...)
> }
> 
>> Note that all of your examples rely not just on recursion but on 
>> heterogeneous recursion
> 
> The crux of the matter is not heterogeneity in general, but of the leaf value 
> in particular. This is what Brent is addressing. All my examples, save one, 
> had a uniform leaf value type (even the Tree example).

The heterogeneity that I'm referring to is the mix of sub-trees and leaves at a 
single level.

> The one exception is my second JSON example. There I did not post the lift 
> operator overload as you can probably imagine it. Minimally:

It's pretty implausible that we'd ever add a "tree literal" concept that serves 
exactly your use case, so I'm looking for ways to capture it that fit within 
the existing language framework, or at least take advantage of a more general 
addition to the language.

Your JSON literal example is already pretty well modeled by simply making a 
JSONValue type that conforms to all the literal protocols.  It is completely 
unclear why you would even want to model this with some generic Tree structure. 
 Note that neither your tree-literal-protocol proposal nor Brent's 
lifting-protocol proposal is actually adequate for embedding non-literal 
Int/Double/Bool values in the structure because they both only allow a single 
"leaf" type.

Your other examples could be modeled with either a lifting protocol or a 
conditional conformance.  I was just noting that the conditional conformance 
would be adequate if you were willing to manually lift non-literal values, and 
conditional conformances are a feature that's already basically planned, as 
opposed to a new research project.

John.






> 
> enum JSONValue {
>   case Text(String)
>   case Integer(Int)
> }
> 
> prefix func ◊  (leaf: String) -> DictionaryTree {
>   return .Leaf(.Text(leaf))
> }
> 
> prefix func ◊  (leaf: Int) -> DictionaryTree {
>   return .Leaf(.Integer(leaf))
> }
> 
> 
> let johnny: DictionaryTree =
> [
>   "name": ◊"Johnny Appleseed",
>   "age": ◊25,
>   "address": [
>   "house_number": ◊21,
>   "street": ◊"2nd Street",
>   "city": ◊"New York"
>   ]
> ]
> 
> Notice in particular how much contextual information you are getting from the 
> expected return type. Still though, as Brent, points out, this won’t work 
> with the two literal-convertable protocols. Nevertheless, I’d be very happy 
> if they could be added as a first step since I suspect that would be the 
> easiest option and one that would still allow for all my examples so far to 
> work without the lift operator; all except this `JSONValue` example.
> 
> milos

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution
Hi John and Brent, 

> On 14 Apr 2016, at 22:22, John McCall  wrote:
> 
> multiple-conformance idea doesn't work


The idea is not multiple-conformance (or overloading), but multiple (two) 
initialisers required by the literal-convertible protocols:

protocol TreeLiteralConvertible {
associatedtype LeafValue
init(literal: Self.LeafValue...)
init(literal: Self...)
}

… and:

protocol DictionaryTreeLiteralConvertible {
associatedtype Key
associatedtype LeafValue
init(literal: Self.LeafValue...)
init(literal: (Key, Self)...)
}

> Note that all of your examples rely not just on recursion but on 
> heterogeneous recursion

The crux of the matter is not heterogeneity in general, but of the leaf value 
in particular. This is what Brent is addressing. All my examples, save one, had 
a uniform leaf value type (even the Tree example). The one exception 
is my second JSON example. There I did not post the lift operator overload as 
you can probably imagine it. Minimally:

enum JSONValue {
case Text(String)
case Integer(Int)
}

prefix func ◊  (leaf: String) -> DictionaryTree {
return .Leaf(.Text(leaf))
}

prefix func ◊  (leaf: Int) -> DictionaryTree {
return .Leaf(.Integer(leaf))
}


let johnny: DictionaryTree =
[
"name": ◊"Johnny Appleseed",
"age": ◊25,
"address": [
"house_number": ◊21,
"street": ◊"2nd Street",
"city": ◊"New York"
]
]

Notice in particular how much contextual information you are getting from the 
expected return type. Still though, as Brent, points out, this won’t work with 
the two literal-convertable protocols. Nevertheless, I’d be very happy if they 
could be added as a first step since I suspect that would be the easiest option 
and one that would still allow for all my examples so far to work without the 
lift operator; all except this `JSONValue` example.

milos___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Brent Royal-Gordon via swift-evolution
>>  extension Tree: LiftingConvertible {
>>  init(lifting value: Value) {
>>  self = .leaf(value)
>>  }
>>  }
> 
> Another name for this feature is "user-defined implicit conversions".

This is absolutely a form of user-defined implicit conversion. It's a limited 
form (one possible `Lifted` for each `LiftingConvertible`), which may help make 
it more feasible, and it is basically a generalization of the special-cased 
Optional lifting, but it is a user-defined implicit conversion.

I understand and agree with the reasons for deferring implicit conversions. 
What I'm saying is that seeing this as a "tree literals" feature is a very 
narrow view of the overall problem.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Dave via swift-evolution
The topic’s come up before. I’m in favor of it, but IIRC there are two problems 
that need to be resolved first:

(I *think* I’m remembering this correctly… don’t quote me on this…)

First, it can cause the type-checker to become “pathological”.
Second, it can cause some *very* unexpected behavior if things are implicitly 
converted through different types than you thought.

- Dave Sweeris

> On Apr 14, 2016, at 4:24 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Apr 14, 2016, at 2:20 PM, Brent Royal-Gordon  
>> wrote:
>>> No, you just need Tree to conform to both ArrayLiteralConvertible and 
>>> IntegerLiteralConvertible, and it implements the latter by building a Value 
>>> out of it.
>> 
>> That not only doesn't work if your type isn't a LiteralConvertible, it also 
>> doesn't work if you want to build a literal with variables:
>> 
>>  let myTree: Tree = [1, [2, three]]
>> 
>> The real missing feature here is implicit lifting like Optional offers. With 
>> a LiftingConvertible protocol, you could say something like this:
>> 
>>  enum Tree {
>>  case leaf(Value)
>>  case branches([Tree])
>>  }
>>  
>>  extension Tree: ArrayLiteralConvertible {
>>  init(arrayLiteral branches: Tree...) {
>>  self = .branches(branches)
>>  }
>>  }
>>  
>>  extension Tree: LiftingConvertible {
>>  init(lifting value: Value) {
>>  self = .leaf(value)
>>  }
>>  }
> 
> Another name for this feature is "user-defined implicit conversions".
> 
> John.
> ___
> 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


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread John McCall via swift-evolution
> On Apr 14, 2016, at 2:20 PM, Brent Royal-Gordon  
> wrote:
>> No, you just need Tree to conform to both ArrayLiteralConvertible and 
>> IntegerLiteralConvertible, and it implements the latter by building a Value 
>> out of it.
> 
> That not only doesn't work if your type isn't a LiteralConvertible, it also 
> doesn't work if you want to build a literal with variables:
> 
>   let myTree: Tree = [1, [2, three]]
> 
> The real missing feature here is implicit lifting like Optional offers. With 
> a LiftingConvertible protocol, you could say something like this:
> 
>   enum Tree {
>   case leaf(Value)
>   case branches([Tree])
>   }
>   
>   extension Tree: ArrayLiteralConvertible {
>   init(arrayLiteral branches: Tree...) {
>   self = .branches(branches)
>   }
>   }
>   
>   extension Tree: LiftingConvertible {
>   init(lifting value: Value) {
>   self = .leaf(value)
>   }
>   }

Another name for this feature is "user-defined implicit conversions".

John.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread John McCall via swift-evolution
> On Apr 14, 2016, at 2:03 PM, Milos Rankovic  
> wrote:
>> On 14 Apr 2016, at 21:36, John McCall > > wrote:
>> 
>> No, you just need Tree to conform to both ArrayLiteralConvertible and 
>> IntegerLiteralConvertible, and it implements the latter by building a Value 
>> out of it.
> 
> You mean this:
> 
> public enum IntTree {
>   case Leaf(Int)
>   case Branches([IntTree])
> }
> 
> extension IntTree : ArrayLiteralConvertible {
>   public init(arrayLiteral elements: IntTree...) {
>   self = .Branches(elements)
>   }
> }
> 
> extension IntTree : IntegerLiteralConvertible {
>   public init(integerLiteral value: IntegerLiteralType) {
>   self = .Leaf(value)
>   }
> }
> 
> let tree: IntTree = [[], 1, [2, 3], [[4, 5], [6, 7], [8, 9]]]
> 
>> you'll simply have to make your Tree less generic
> 
> 
> Yep, that’s the rub… With generic trees you can express yourself freely, 
> whether you feel like:
> 
> import SpriteKit
> 
> let actionTree: Tree = [
>   ◊.waitForDuration(1),
>   [
>   ◊.fadeInWithDuration(1),
>   ◊.scaleTo(1, duration: 1)
>   ],
>   ◊.playSoundFileNamed("TaDa", waitForCompletion: false)
> ]
> 
> … or:
> 
> let johnny: DictionaryTree =
> [
>   "name": ◊"Johnny Appleseed",
>   "age": ◊25,
>   "address": [
>   "house_number": ◊21,
>   "street": ◊"2nd Street",
>   "city": ◊"New York"
>   ]
> ]
> 
> I’d just love to get rid of that prefix operator…

Note that all of your examples rely not just on recursion but on heterogeneous 
recursion, so the multiple-conformance idea doesn't work.  Fundamentally, your 
trees have a payload type that needs to be constructible from different kinds 
of literal.  It's appropriate to model that with conformance to multiple 
protocols.  The ability to do that conditionally based on whether another type 
declares a conformance is called "conditional conformance", and it's already 
something we're strongly considering for the future; it's just not an easy 
feature to actually implement.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Dave via swift-evolution
I think a better solution than just adding a TreeLiteral (and the accompanying 
TreeLiteralConvertible protocol) would be to allow user-defined literal types 
using regex (or something similar). This would not only allow for tremendous 
flexibility, but it’d remove some compiler magic as well.

There’d have to be some rules regarding overlapping definitions… The simplest I 
can think of is make it an error to not do type annotation when there’s more 
than one way to parse a literal, but I’m not sure that’s necessarily the best.

- Dave Sweeris

> On Apr 14, 2016, at 11:27 AM, 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 {
>   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 ◊  (leaf: T) -> Tree { return .Leaf(leaf) }
> 
> let tree: Tree = [[], ◊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 = [[], 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 {
>   case Leaf(Value)
>   case Branches([(Key, DictionaryTree)])
> }
> 
> extension DictionaryTree : DictionaryLiteralConvertible {
>   init(dictionaryLiteral pairs: (Key, DictionaryTree)...) {
>   self = .Branches(pairs)
>   }
> }
> 
> prefix func ◊  (leaf: Value) -> DictionaryTree { 
> return .Leaf(leaf) }
> 
> let map: DictionaryTree = [
>   "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


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Brent Royal-Gordon via swift-evolution
> No, you just need Tree to conform to both ArrayLiteralConvertible and 
> IntegerLiteralConvertible, and it implements the latter by building a Value 
> out of it.

That not only doesn't work if your type isn't a LiteralConvertible, it also 
doesn't work if you want to build a literal with variables:

let myTree: Tree = [1, [2, three]]

The real missing feature here is implicit lifting like Optional offers. With a 
LiftingConvertible protocol, you could say something like this:

enum Tree {
case leaf(Value)
case branches([Tree])
}

extension Tree: ArrayLiteralConvertible {
init(arrayLiteral branches: Tree...) {
self = .branches(branches)
}
}

extension Tree: LiftingConvertible {
init(lifting value: Value) {
self = .leaf(value)
}
}

However, even without implicit lifting, you should still be able to write trees 
with just ArrayLiteralConvertible by explicitly lifting the leaves:

let myTree: Tree = [.leaf(1), [.leaf(2), .leaf(three)]]

That isn't great, but it's not awful, either.

For that matter, you could write a semi-implicit lifting feature:

protocol LiftingConvertible {
associatedtype Lifted
init(lifting value: Lifted)
}

prefix operator ^ {}
prefix func ^  (lifted: Lifting.Lifted) -> 
Lifting {
return Lifting(lifting: lifted)
}

let myTree: Tree = [^1, [^2, ^three]]

That's actually not so bad.

-- 
Brent Royal-Gordon
Architechies

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution

> On 14 Apr 2016, at 21:36, John McCall  wrote:
> 
> No, you just need Tree to conform to both ArrayLiteralConvertible and 
> IntegerLiteralConvertible, and it implements the latter by building a Value 
> out of it.

You mean this:

public enum IntTree {
case Leaf(Int)
case Branches([IntTree])
}

extension IntTree : ArrayLiteralConvertible {
public init(arrayLiteral elements: IntTree...) {
self = .Branches(elements)
}
}

extension IntTree : IntegerLiteralConvertible {
public init(integerLiteral value: IntegerLiteralType) {
self = .Leaf(value)
}
}

let tree: IntTree = [[], 1, [2, 3], [[4, 5], [6, 7], [8, 9]]]

> you'll simply have to make your Tree less generic


Yep, that’s the rub… With generic trees you can express yourself freely, 
whether you feel like:

import SpriteKit

let actionTree: Tree = [
◊.waitForDuration(1),
[
◊.fadeInWithDuration(1),
◊.scaleTo(1, duration: 1)
],
◊.playSoundFileNamed("TaDa", waitForCompletion: false)
]

… or:

let johnny: DictionaryTree =
[
"name": ◊"Johnny Appleseed",
"age": ◊25,
"address": [
"house_number": ◊21,
"street": ◊"2nd Street",
"city": ◊"New York"
]
]

I’d just love to get rid of that prefix operator…

milos









___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread John McCall via swift-evolution
> On Apr 14, 2016, at 1:34 PM, Milos Rankovic  
> wrote:
> Hi John,
> 
>> On 14 Apr 2016, at 21:09, John McCall > > wrote:
>> 
>> I mean, you could just make your Tree type implement all the individual 
>> literal-convertible protocols.
> 
> It does sound like something like that should be doable, but it isn’t. The 
> literal-convertible protocols only require one initialiser, but you need two: 
> one that lifts leaf values to Self and the other that actually takes Self 
> elements (it is this last one that provides for recursion). In other words, 
> we’d need to overload our conformance:
> 
> extension Tree : ArrayLiteralConvertible { // error: does not conform!
>   init(arrayLiteral elements: Tree...) {
>   self = .Branches(elements)
>   }
>   init(arrayLiteral elements: Value...) {
>   if elements.count == 1 { self = .Leaf(elements[0]) }
>   else { self = .Branches(elements.map{ .Leaf($0) }) }
>   }
> }
> 
> But you can only conform in one or the other way, but not both! Therefore, 
> for trees, we need something like:
> 
> protocol TreeLiteralConvertible {
>   associatedtype LeafValue
>   init(literal: Self.LeafValue...)
>   init(literal: Self...)
> }

No, you just need Tree to conform to both ArrayLiteralConvertible and 
IntegerLiteralConvertible, and it implements the latter by building a Value out 
of it.

This would be easily done with conditional conformance; as it is, you'll simply 
have to make your Tree less generic, e.g. by always requiring Value to be 
IntegerLiteralConvertible.  Of course, this would not be a problem for a JSON 
tree, which would not be generic at all.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution
Hi John,

> On 14 Apr 2016, at 21:09, John McCall  wrote:
> 
> I mean, you could just make your Tree type implement all the individual 
> literal-convertible protocols.

It does sound like something like that should be doable, but it isn’t. The 
literal-convertible protocols only require one initialiser, but you need two: 
one that lifts leaf values to Self and the other that actually takes Self 
elements (it is this last one that provides for recursion). In other words, 
we’d need to overload our conformance:

extension Tree : ArrayLiteralConvertible { // error: does not conform!
init(arrayLiteral elements: Tree...) {
self = .Branches(elements)
}
init(arrayLiteral elements: Value...) {
if elements.count == 1 { self = .Leaf(elements[0]) }
else { self = .Branches(elements.map{ .Leaf($0) }) }
}
}

But you can only conform in one or the other way, but not both! Therefore, for 
trees, we need something like:

protocol TreeLiteralConvertible {
associatedtype LeafValue
init(literal: Self.LeafValue...)
init(literal: Self...)
}

milos___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread John McCall via swift-evolution
> On Apr 14, 2016, at 12:01 PM, Milos Rankovic via swift-evolution 
>  wrote:
> Hi Andrey and Laurent,
> 
>> On 14 Apr 2016, at 19:23, Andrey Tarantsov > > wrote:
>> 
>> 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.
> 
> I suppose we always prefer to move *all* data into databases or files with 
> dedicated data formats, *including* arrays, strings, dictionaries, etc. Sure. 
> But it would be rather underwhelming if you could not also just instantiate 
> an array or a string from a literal.
> 
>> On 14 Apr 2016, at 19:33, L Mihalkovic > > wrote:
>> 
>> I’d rather the language do NOT make it easy to have complex literals 
>> initializations
> 
> 
> I agree, except, something like `[1, [2]]` doesn’t immediately strike me by 
> its complexity. Likewise, I find it a little deflating that I cannot express 
> a piece of JSON in code. My example structures do allow you to write:
> 
> let _: DictionaryTree =
> [
>   "name": ◊"Johnny Appleseed",
>   "address": [
>   "streetAddress": ◊"21 2nd Street",
>   "city": ◊"New York"
>   ]
> ]
> 
> … but I cannot get rid of that prefix operator without the additional 
> literal-convertible protocols. Given the *simplicity* of these structures, it 
> seems it should not be beyond Swift to represent them in code with ease and 
> elegance. And to begin with, all we need are those couple of protocols.

I mean, you could just make your Tree type implement all the individual 
literal-convertible protocols.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution
Hi Andrey and Laurent,

> On 14 Apr 2016, at 19:23, Andrey Tarantsov  wrote:
> 
> 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.

I suppose we always prefer to move *all* data into databases or files with 
dedicated data formats, *including* arrays, strings, dictionaries, etc. Sure. 
But it would be rather underwhelming if you could not also just instantiate an 
array or a string from a literal.

> On 14 Apr 2016, at 19:33, L Mihalkovic  wrote:
> 
> I’d rather the language do NOT make it easy to have complex literals 
> initializations


I agree, except, something like `[1, [2]]` doesn’t immediately strike me by its 
complexity. Likewise, I find it a little deflating that I cannot express a 
piece of JSON in code. My example structures do allow you to write:

let _: DictionaryTree =
[
"name": ◊"Johnny Appleseed",
"address": [
"streetAddress": ◊"21 2nd Street",
"city": ◊"New York"
]
]

… but I cannot get rid of that prefix operator without the additional 
literal-convertible protocols. Given the *simplicity* of these structures, it 
seems it should not be beyond Swift to represent them in code with ease and 
elegance. And to begin with, all we need are those couple of protocols.

milos___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread L Mihalkovic via swift-evolution


> On Apr 14, 2016, at 8:23 PM, Andrey Tarantsov via swift-evolution 
>  wrote:
> 
> 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.
> 


ditto. 
This is where in the simplest case I write a simple text(json) file, and in the 
more extreme cases, write a custom DSL+Eclipse Editor to deal with a complete 
custom file format (I said extreme.. but I did do it). I would even go 
further.. I’d rather the language do NOT make it easy to have complex literals 
initializations to avoid having to chase critical CONFIG elements in the source 
code. D has an interesting concept if you REALLY want do data in code: import 
(“data_in_code.d”) 

> 
>> On Apr 14, 2016, at 10:27 PM, 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 {
>>  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 ◊  (leaf: T) -> Tree { return .Leaf(leaf) }
>> 
>> let tree: Tree = [[], ◊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 = [[], 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 {
>>  case Leaf(Value)
>>  case Branches([(Key, DictionaryTree)])
>> }
>> 
>> extension DictionaryTree : DictionaryLiteralConvertible {
>>  init(dictionaryLiteral pairs: (Key, DictionaryTree)...) {
>>  self = .Branches(pairs)
>>  }
>> }
>> 
>> prefix func ◊  (leaf: Value) -> DictionaryTree { 
>> return .Leaf(leaf) }
>> 
>> let map: DictionaryTree = [
>>  "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

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Andrey Tarantsov via swift-evolution
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 
>  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 {
>   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 ◊  (leaf: T) -> Tree { return .Leaf(leaf) }
> 
> let tree: Tree = [[], ◊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 = [[], 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 {
>   case Leaf(Value)
>   case Branches([(Key, DictionaryTree)])
> }
> 
> extension DictionaryTree : DictionaryLiteralConvertible {
>   init(dictionaryLiteral pairs: (Key, DictionaryTree)...) {
>   self = .Branches(pairs)
>   }
> }
> 
> prefix func ◊  (leaf: Value) -> DictionaryTree { 
> return .Leaf(leaf) }
> 
> let map: DictionaryTree = [
>   "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


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution
> On 14 Apr 2016, at 13:26, Milos Rankovic via swift-evolution 
>  wrote:

Please disregard this, the earlier of the two posts with the subject 
“TreeLiteralConvertible". I appears it escaped me while composing. 

With embarrassment and apologies,

milos___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Milos Rankovic via swift-evolution
Thanks for the comment, Vladimir. 

> On 14 Apr 2016, at 18:14, Vladimir.S  wrote:
> 
> Well, actually we can compile :
> 
> var zz : [Any] = [[Int](), 1,  [2, 3], [[4, 5], [6, 7], [8, 9]]]
> 
Sure. I just wasn’t sure it was worth mentioning (it was a long post anyway): 
annotating the variable with `[Any]` is not preserving the leaf type nor does 
it do justice to the overall structure.

milos___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] TreeLiteralConvertible

2016-04-14 Thread Vladimir.S via swift-evolution

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 {
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 ◊  (leaf: T) -> Tree { return .Leaf(leaf) }

let tree: Tree = [[], ◊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 = [[], 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 {
case Leaf(Value)
case Branches([(Key, DictionaryTree)])
}

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

prefixfunc ◊  (leaf: Value) -> DictionaryTree {
return .Leaf(leaf) }

let map: DictionaryTree = [
"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
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