[swift-evolution] TreeLiteralConvertible
John McCall
rjmccall at apple.com
Thu Apr 14 21:22:53 CDT 2016
> On Apr 14, 2016, at 2:56 PM, Milos Rankovic <milos at milos-and-slavica.net> wrote:
> Hi John and Brent,
>
>> On 14 Apr 2016, at 22:22, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> 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<SKAction> 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 ◊ <Key> (leaf: String) -> DictionaryTree<Key, JSONValue> {
> return .Leaf(.Text(leaf))
> }
>
> prefix func ◊ <Key> (leaf: Int) -> DictionaryTree<Key, JSONValue> {
> return .Leaf(.Integer(leaf))
> }
>
>
> let johnny: DictionaryTree<String, JSONValue> =
> [
> "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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160414/c1cf8b22/attachment.html>
More information about the swift-evolution
mailing list