TreeLiteralConvertible

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<String, AnyObject>. I even typealias that as JSONObject, and have a lot of code parsing and producing these. While TreeDictionary<String, String> 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: GitHub - ExpressiveSwift/ExpressiveCasting: Defensive parsing of untyped and potentially untrusted data (JSON APIs, User Defaults and such). One of ExpressiveSwift µ-frameworks.

A.

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<String, JSONValue>, you'll end up with two different ways to represent { "x" : { "y" : 1 } }. It's much better to use the "flat" representation of Dictionary<String, JSONValue> and allow the JSONValue enum's natural recursiveness to express nested objects.

John.

···

On Apr 15, 2016, at 1:29 AM, Milos Rankovic <milos@milos-and-slavica.net> wrote:

On 15 Apr 2016, at 03:22, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> 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<String, JSONValue>`, in contrast, precisely expresses the structure of JSON objects.

let example: Tree<String> =
[
  "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?"
  ]
]

···

On 15 Apr 2016, at 08:24, Andrey Tarantsov <andrey@tarantsov.com> wrote:

On 14 Apr 2016, at 19:23, Andrey Tarantsov <andrey@tarantsov.com> 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.)

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.

···

On 15 Apr 2016, at 16:48, John McCall via swift-evolution <swift-evolution@swift.org> 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)

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

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<String, JSONValue> =
[
  "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<String, JSONValue>)
}

milos

···

On 15 Apr 2016, at 19:54, Haravikk <swift-evolution@haravikk.me> 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.